12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
- <meta property="og:title" content="9. Classes" />
- <meta property="og:type" content="website" />
- <meta property="og:url" content="https://docs.python.org/3/tutorial/classes.html" />
- <meta property="og:site_name" content="Python documentation" />
- <meta property="og:description" content="Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have ..." />
- <meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
- <meta property="og:image:alt" content="Python documentation" />
- <meta name="description" content="Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have ..." />
- <meta property="og:image:width" content="200" />
- <meta property="og:image:height" content="200" />
- <meta name="theme-color" content="#3776ab" />
- <title>9. Classes — Python 3.12.0 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
-
- <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
- <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?digest=b37c26da2f7529d09fe70b41c4b2133fe4931a90" />
- <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css" />
-
- <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
-
- <script src="../_static/sidebar.js"></script>
-
- <link rel="search" type="application/opensearchdescription+xml"
- title="Search within Python 3.12.0 documentation"
- href="../_static/opensearch.xml"/>
- <link rel="author" title="About these documents" href="../about.html" />
- <link rel="index" title="Index" href="../genindex.html" />
- <link rel="search" title="Search" href="../search.html" />
- <link rel="copyright" title="Copyright" href="../copyright.html" />
- <link rel="next" title="10. Brief Tour of the Standard Library" href="stdlib.html" />
- <link rel="prev" title="8. Errors and Exceptions" href="errors.html" />
- <link rel="canonical" href="https://docs.python.org/3/tutorial/classes.html" />
-
-
-
-
- <style>
- @media only screen {
- table.full-width-table {
- width: 100%;
- }
- }
- </style>
- <link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
- <link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
- <script type="text/javascript" src="../_static/copybutton.js"></script>
- <script type="text/javascript" src="../_static/menu.js"></script>
- <script type="text/javascript" src="../_static/themetoggle.js"></script>
- </head>
- <body>
- <div class="mobile-nav">
- <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
- aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
- <nav class="nav-content" role="navigation">
- <label for="menuToggler" class="toggler__label">
- <span></span>
- </label>
- <span class="nav-items-wrapper">
- <a href="https://www.python.org/" class="nav-logo">
- <img src="../_static/py.svg" alt="Logo"/>
- </a>
- <span class="version_switcher_placeholder"></span>
- <form role="search" class="search" action="../search.html" method="get">
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
- <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
- </svg>
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go"/>
- </form>
- </span>
- </nav>
- <div class="menu-wrapper">
- <nav class="menu" role="navigation" aria-label="main navigation">
- <div class="language_switcher_placeholder"></div>
-
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label>
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">9. Classes</a><ul>
- <li><a class="reference internal" href="#a-word-about-names-and-objects">9.1. A Word About Names and Objects</a></li>
- <li><a class="reference internal" href="#python-scopes-and-namespaces">9.2. Python Scopes and Namespaces</a><ul>
- <li><a class="reference internal" href="#scopes-and-namespaces-example">9.2.1. Scopes and Namespaces Example</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#a-first-look-at-classes">9.3. A First Look at Classes</a><ul>
- <li><a class="reference internal" href="#class-definition-syntax">9.3.1. Class Definition Syntax</a></li>
- <li><a class="reference internal" href="#class-objects">9.3.2. Class Objects</a></li>
- <li><a class="reference internal" href="#instance-objects">9.3.3. Instance Objects</a></li>
- <li><a class="reference internal" href="#method-objects">9.3.4. Method Objects</a></li>
- <li><a class="reference internal" href="#class-and-instance-variables">9.3.5. Class and Instance Variables</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#random-remarks">9.4. Random Remarks</a></li>
- <li><a class="reference internal" href="#inheritance">9.5. Inheritance</a><ul>
- <li><a class="reference internal" href="#multiple-inheritance">9.5.1. Multiple Inheritance</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#private-variables">9.6. Private Variables</a></li>
- <li><a class="reference internal" href="#odds-and-ends">9.7. Odds and Ends</a></li>
- <li><a class="reference internal" href="#iterators">9.8. Iterators</a></li>
- <li><a class="reference internal" href="#generators">9.9. Generators</a></li>
- <li><a class="reference internal" href="#generator-expressions">9.10. Generator Expressions</a></li>
- </ul>
- </li>
- </ul>
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="errors.html"
- title="previous chapter"><span class="section-number">8. </span>Errors and Exceptions</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="stdlib.html"
- title="next chapter"><span class="section-number">10. </span>Brief Tour of the Standard Library</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/tutorial/classes.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </nav>
- </div>
- </div>
-
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- accesskey="I">index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="stdlib.html" title="10. Brief Tour of the Standard Library"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="errors.html" title="8. Errors and Exceptions"
- accesskey="P">previous</a> |</li>
- <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.0 Documentation</a> »
- </li>
- <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">The Python Tutorial</a> »</li>
- <li class="nav-item nav-item-this"><a href=""><span class="section-number">9. </span>Classes</a></li>
- <li class="right">
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body" role="main">
-
- <section id="classes">
- <span id="tut-classes"></span><h1><span class="section-number">9. </span>Classes<a class="headerlink" href="#classes" title="Permalink to this headline">¶</a></h1>
- <p>Classes provide a means of bundling data and functionality together. Creating
- a new class creates a new <em>type</em> of object, allowing new <em>instances</em> of that
- type to be made. Each class instance can have attributes attached to it for
- maintaining its state. Class instances can also have methods (defined by its
- class) for modifying its state.</p>
- <p>Compared with other programming languages, Python’s class mechanism adds classes
- with a minimum of new syntax and semantics. It is a mixture of the class
- mechanisms found in C++ and Modula-3. Python classes provide all the standard
- features of Object Oriented Programming: the class inheritance mechanism allows
- multiple base classes, a derived class can override any methods of its base
- class or classes, and a method can call the method of a base class with the same
- name. Objects can contain arbitrary amounts and kinds of data. As is true for
- modules, classes partake of the dynamic nature of Python: they are created at
- runtime, and can be modified further after creation.</p>
- <p>In C++ terminology, normally class members (including the data members) are
- <em>public</em> (except see below <a class="reference internal" href="#tut-private"><span class="std std-ref">Private Variables</span></a>), and all member functions are
- <em>virtual</em>. As in Modula-3, there are no shorthands for referencing the object’s
- members from its methods: the method function is declared with an explicit first
- argument representing the object, which is provided implicitly by the call. As
- in Smalltalk, classes themselves are objects. This provides semantics for
- importing and renaming. Unlike C++ and Modula-3, built-in types can be used as
- base classes for extension by the user. Also, like in C++, most built-in
- operators with special syntax (arithmetic operators, subscripting etc.) can be
- redefined for class instances.</p>
- <p>(Lacking universally accepted terminology to talk about classes, I will make
- occasional use of Smalltalk and C++ terms. I would use Modula-3 terms, since
- its object-oriented semantics are closer to those of Python than C++, but I
- expect that few readers have heard of it.)</p>
- <section id="a-word-about-names-and-objects">
- <span id="tut-object"></span><h2><span class="section-number">9.1. </span>A Word About Names and Objects<a class="headerlink" href="#a-word-about-names-and-objects" title="Permalink to this headline">¶</a></h2>
- <p>Objects have individuality, and multiple names (in multiple scopes) can be bound
- to the same object. This is known as aliasing in other languages. This is
- usually not appreciated on a first glance at Python, and can be safely ignored
- when dealing with immutable basic types (numbers, strings, tuples). However,
- aliasing has a possibly surprising effect on the semantics of Python code
- involving mutable objects such as lists, dictionaries, and most other types.
- This is usually used to the benefit of the program, since aliases behave like
- pointers in some respects. For example, passing an object is cheap since only a
- pointer is passed by the implementation; and if a function modifies an object
- passed as an argument, the caller will see the change — this eliminates the
- need for two different argument passing mechanisms as in Pascal.</p>
- </section>
- <section id="python-scopes-and-namespaces">
- <span id="tut-scopes"></span><h2><span class="section-number">9.2. </span>Python Scopes and Namespaces<a class="headerlink" href="#python-scopes-and-namespaces" title="Permalink to this headline">¶</a></h2>
- <p>Before introducing classes, I first have to tell you something about Python’s
- scope rules. Class definitions play some neat tricks with namespaces, and you
- need to know how scopes and namespaces work to fully understand what’s going on.
- Incidentally, knowledge about this subject is useful for any advanced Python
- programmer.</p>
- <p>Let’s begin with some definitions.</p>
- <p>A <em>namespace</em> is a mapping from names to objects. Most namespaces are currently
- implemented as Python dictionaries, but that’s normally not noticeable in any
- way (except for performance), and it may change in the future. Examples of
- namespaces are: the set of built-in names (containing functions such as <a class="reference internal" href="../library/functions.html#abs" title="abs"><code class="xref py py-func docutils literal notranslate"><span class="pre">abs()</span></code></a>, and
- built-in exception names); the global names in a module; and the local names in
- a function invocation. In a sense the set of attributes of an object also form
- a namespace. The important thing to know about namespaces is that there is
- absolutely no relation between names in different namespaces; for instance, two
- different modules may both define a function <code class="docutils literal notranslate"><span class="pre">maximize</span></code> without confusion —
- users of the modules must prefix it with the module name.</p>
- <p>By the way, I use the word <em>attribute</em> for any name following a dot — for
- example, in the expression <code class="docutils literal notranslate"><span class="pre">z.real</span></code>, <code class="docutils literal notranslate"><span class="pre">real</span></code> is an attribute of the object
- <code class="docutils literal notranslate"><span class="pre">z</span></code>. Strictly speaking, references to names in modules are attribute
- references: in the expression <code class="docutils literal notranslate"><span class="pre">modname.funcname</span></code>, <code class="docutils literal notranslate"><span class="pre">modname</span></code> is a module
- object and <code class="docutils literal notranslate"><span class="pre">funcname</span></code> is an attribute of it. In this case there happens to be
- a straightforward mapping between the module’s attributes and the global names
- defined in the module: they share the same namespace! <a class="footnote-reference brackets" href="#id2" id="id1">1</a></p>
- <p>Attributes may be read-only or writable. In the latter case, assignment to
- attributes is possible. Module attributes are writable: you can write
- <code class="docutils literal notranslate"><span class="pre">modname.the_answer</span> <span class="pre">=</span> <span class="pre">42</span></code>. Writable attributes may also be deleted with the
- <a class="reference internal" href="../reference/simple_stmts.html#del"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code></a> statement. For example, <code class="docutils literal notranslate"><span class="pre">del</span> <span class="pre">modname.the_answer</span></code> will remove
- the attribute <code class="xref py py-attr docutils literal notranslate"><span class="pre">the_answer</span></code> from the object named by <code class="docutils literal notranslate"><span class="pre">modname</span></code>.</p>
- <p>Namespaces are created at different moments and have different lifetimes. The
- namespace containing the built-in names is created when the Python interpreter
- starts up, and is never deleted. The global namespace for a module is created
- when the module definition is read in; normally, module namespaces also last
- until the interpreter quits. The statements executed by the top-level
- invocation of the interpreter, either read from a script file or interactively,
- are considered part of a module called <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where top-level code is run. Covers command-line interfaces, import-time behavior, and ``__name__ == '__main__'``."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a>, so they have their own
- global namespace. (The built-in names actually also live in a module; this is
- called <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a>.)</p>
- <p>The local namespace for a function is created when the function is called, and
- deleted when the function returns or raises an exception that is not handled
- within the function. (Actually, forgetting would be a better way to describe
- what actually happens.) Of course, recursive invocations each have their own
- local namespace.</p>
- <p>A <em>scope</em> is a textual region of a Python program where a namespace is directly
- accessible. “Directly accessible” here means that an unqualified reference to a
- name attempts to find the name in the namespace.</p>
- <p>Although scopes are determined statically, they are used dynamically. At any
- time during execution, there are 3 or 4 nested scopes whose namespaces are
- directly accessible:</p>
- <ul class="simple">
- <li><p>the innermost scope, which is searched first, contains the local names</p></li>
- <li><p>the scopes of any enclosing functions, which are searched starting with the
- nearest enclosing scope, contain non-local, but also non-global names</p></li>
- <li><p>the next-to-last scope contains the current module’s global names</p></li>
- <li><p>the outermost scope (searched last) is the namespace containing built-in names</p></li>
- </ul>
- <p>If a name is declared global, then all references and assignments go directly to
- the next-to-last scope containing the module’s global names. To rebind variables
- found outside of the innermost scope, the <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> statement can be
- used; if not declared nonlocal, those variables are read-only (an attempt to
- write to such a variable will simply create a <em>new</em> local variable in the
- innermost scope, leaving the identically named outer variable unchanged).</p>
- <p>Usually, the local scope references the local names of the (textually) current
- function. Outside functions, the local scope references the same namespace as
- the global scope: the module’s namespace. Class definitions place yet another
- namespace in the local scope.</p>
- <p>It is important to realize that scopes are determined textually: the global
- scope of a function defined in a module is that module’s namespace, no matter
- from where or by what alias the function is called. On the other hand, the
- actual search for names is done dynamically, at run time — however, the
- language definition is evolving towards static name resolution, at “compile”
- time, so don’t rely on dynamic name resolution! (In fact, local variables are
- already determined statically.)</p>
- <p>A special quirk of Python is that – if no <a class="reference internal" href="../reference/simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> or <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a>
- statement is in effect – assignments to names always go into the innermost scope.
- Assignments do not copy data — they just bind names to objects. The same is true
- for deletions: the statement <code class="docutils literal notranslate"><span class="pre">del</span> <span class="pre">x</span></code> removes the binding of <code class="docutils literal notranslate"><span class="pre">x</span></code> from the
- namespace referenced by the local scope. In fact, all operations that introduce
- new names use the local scope: in particular, <a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> statements and
- function definitions bind the module or function name in the local scope.</p>
- <p>The <a class="reference internal" href="../reference/simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> statement can be used to indicate that particular
- variables live in the global scope and should be rebound there; the
- <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> statement indicates that particular variables live in
- an enclosing scope and should be rebound there.</p>
- <section id="scopes-and-namespaces-example">
- <span id="tut-scopeexample"></span><h3><span class="section-number">9.2.1. </span>Scopes and Namespaces Example<a class="headerlink" href="#scopes-and-namespaces-example" title="Permalink to this headline">¶</a></h3>
- <p>This is an example demonstrating how to reference the different scopes and
- namespaces, and how <a class="reference internal" href="../reference/simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> and <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> affect variable
- binding:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">scope_test</span><span class="p">():</span>
- <span class="k">def</span> <span class="nf">do_local</span><span class="p">():</span>
- <span class="n">spam</span> <span class="o">=</span> <span class="s2">"local spam"</span>
- <span class="k">def</span> <span class="nf">do_nonlocal</span><span class="p">():</span>
- <span class="k">nonlocal</span> <span class="n">spam</span>
- <span class="n">spam</span> <span class="o">=</span> <span class="s2">"nonlocal spam"</span>
- <span class="k">def</span> <span class="nf">do_global</span><span class="p">():</span>
- <span class="k">global</span> <span class="n">spam</span>
- <span class="n">spam</span> <span class="o">=</span> <span class="s2">"global spam"</span>
- <span class="n">spam</span> <span class="o">=</span> <span class="s2">"test spam"</span>
- <span class="n">do_local</span><span class="p">()</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"After local assignment:"</span><span class="p">,</span> <span class="n">spam</span><span class="p">)</span>
- <span class="n">do_nonlocal</span><span class="p">()</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"After nonlocal assignment:"</span><span class="p">,</span> <span class="n">spam</span><span class="p">)</span>
- <span class="n">do_global</span><span class="p">()</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"After global assignment:"</span><span class="p">,</span> <span class="n">spam</span><span class="p">)</span>
- <span class="n">scope_test</span><span class="p">()</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"In global scope:"</span><span class="p">,</span> <span class="n">spam</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>The output of the example code is:</p>
- <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>After local assignment: test spam
- After nonlocal assignment: nonlocal spam
- After global assignment: nonlocal spam
- In global scope: global spam
- </pre></div>
- </div>
- <p>Note how the <em>local</em> assignment (which is default) didn’t change <em>scope_test</em>'s
- binding of <em>spam</em>. The <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> assignment changed <em>scope_test</em>'s
- binding of <em>spam</em>, and the <a class="reference internal" href="../reference/simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> assignment changed the module-level
- binding.</p>
- <p>You can also see that there was no previous binding for <em>spam</em> before the
- <a class="reference internal" href="../reference/simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> assignment.</p>
- </section>
- </section>
- <section id="a-first-look-at-classes">
- <span id="tut-firstclasses"></span><h2><span class="section-number">9.3. </span>A First Look at Classes<a class="headerlink" href="#a-first-look-at-classes" title="Permalink to this headline">¶</a></h2>
- <p>Classes introduce a little bit of new syntax, three new object types, and some
- new semantics.</p>
- <section id="class-definition-syntax">
- <span id="tut-classdefinition"></span><h3><span class="section-number">9.3.1. </span>Class Definition Syntax<a class="headerlink" href="#class-definition-syntax" title="Permalink to this headline">¶</a></h3>
- <p>The simplest form of class definition looks like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ClassName</span><span class="p">:</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="mi">1</span><span class="o">></span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="n">N</span><span class="o">></span>
- </pre></div>
- </div>
- <p>Class definitions, like function definitions (<a class="reference internal" href="../reference/compound_stmts.html#def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">def</span></code></a> statements) must be
- executed before they have any effect. (You could conceivably place a class
- definition in a branch of an <a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> statement, or inside a function.)</p>
- <p>In practice, the statements inside a class definition will usually be function
- definitions, but other statements are allowed, and sometimes useful — we’ll
- come back to this later. The function definitions inside a class normally have
- a peculiar form of argument list, dictated by the calling conventions for
- methods — again, this is explained later.</p>
- <p>When a class definition is entered, a new namespace is created, and used as the
- local scope — thus, all assignments to local variables go into this new
- namespace. In particular, function definitions bind the name of the new
- function here.</p>
- <p>When a class definition is left normally (via the end), a <em>class object</em> is
- created. This is basically a wrapper around the contents of the namespace
- created by the class definition; we’ll learn more about class objects in the
- next section. The original local scope (the one in effect just before the class
- definition was entered) is reinstated, and the class object is bound here to the
- class name given in the class definition header (<code class="xref py py-class docutils literal notranslate"><span class="pre">ClassName</span></code> in the
- example).</p>
- </section>
- <section id="class-objects">
- <span id="tut-classobjects"></span><h3><span class="section-number">9.3.2. </span>Class Objects<a class="headerlink" href="#class-objects" title="Permalink to this headline">¶</a></h3>
- <p>Class objects support two kinds of operations: attribute references and
- instantiation.</p>
- <p><em>Attribute references</em> use the standard syntax used for all attribute references
- in Python: <code class="docutils literal notranslate"><span class="pre">obj.name</span></code>. Valid attribute names are all the names that were in
- the class’s namespace when the class object was created. So, if the class
- definition looked like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyClass</span><span class="p">:</span>
- <span class="w"> </span><span class="sd">"""A simple example class"""</span>
- <span class="n">i</span> <span class="o">=</span> <span class="mi">12345</span>
- <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">return</span> <span class="s1">'hello world'</span>
- </pre></div>
- </div>
- <p>then <code class="docutils literal notranslate"><span class="pre">MyClass.i</span></code> and <code class="docutils literal notranslate"><span class="pre">MyClass.f</span></code> are valid attribute references, returning
- an integer and a function object, respectively. Class attributes can also be
- assigned to, so you can change the value of <code class="docutils literal notranslate"><span class="pre">MyClass.i</span></code> by assignment.
- <code class="xref py py-attr docutils literal notranslate"><span class="pre">__doc__</span></code> is also a valid attribute, returning the docstring belonging to
- the class: <code class="docutils literal notranslate"><span class="pre">"A</span> <span class="pre">simple</span> <span class="pre">example</span> <span class="pre">class"</span></code>.</p>
- <p>Class <em>instantiation</em> uses function notation. Just pretend that the class
- object is a parameterless function that returns a new instance of the class.
- For example (assuming the above class):</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">MyClass</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>creates a new <em>instance</em> of the class and assigns this object to the local
- variable <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p>
- <p>The instantiation operation (“calling” a class object) creates an empty object.
- Many classes like to create objects with instances customized to a specific
- initial state. Therefore a class may define a special method named
- <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a>, like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
- </pre></div>
- </div>
- <p>When a class defines an <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method, class instantiation
- automatically invokes <code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code> for the newly created class instance. So
- in this example, a new, initialized instance can be obtained by:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">MyClass</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>Of course, the <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method may have arguments for greater
- flexibility. In that case, arguments given to the class instantiation operator
- are passed on to <code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code>. For example,</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Complex</span><span class="p">:</span>
- <span class="gp">... </span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">realpart</span><span class="p">,</span> <span class="n">imagpart</span><span class="p">):</span>
- <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">r</span> <span class="o">=</span> <span class="n">realpart</span>
- <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">i</span> <span class="o">=</span> <span class="n">imagpart</span>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">x</span> <span class="o">=</span> <span class="n">Complex</span><span class="p">(</span><span class="mf">3.0</span><span class="p">,</span> <span class="o">-</span><span class="mf">4.5</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">x</span><span class="o">.</span><span class="n">r</span><span class="p">,</span> <span class="n">x</span><span class="o">.</span><span class="n">i</span>
- <span class="go">(3.0, -4.5)</span>
- </pre></div>
- </div>
- </section>
- <section id="instance-objects">
- <span id="tut-instanceobjects"></span><h3><span class="section-number">9.3.3. </span>Instance Objects<a class="headerlink" href="#instance-objects" title="Permalink to this headline">¶</a></h3>
- <p>Now what can we do with instance objects? The only operations understood by
- instance objects are attribute references. There are two kinds of valid
- attribute names: data attributes and methods.</p>
- <p><em>data attributes</em> correspond to “instance variables” in Smalltalk, and to “data
- members” in C++. Data attributes need not be declared; like local variables,
- they spring into existence when they are first assigned to. For example, if
- <code class="docutils literal notranslate"><span class="pre">x</span></code> is the instance of <code class="xref py py-class docutils literal notranslate"><span class="pre">MyClass</span></code> created above, the following piece of
- code will print the value <code class="docutils literal notranslate"><span class="pre">16</span></code>, without leaving a trace:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span><span class="o">.</span><span class="n">counter</span> <span class="o">=</span> <span class="mi">1</span>
- <span class="k">while</span> <span class="n">x</span><span class="o">.</span><span class="n">counter</span> <span class="o"><</span> <span class="mi">10</span><span class="p">:</span>
- <span class="n">x</span><span class="o">.</span><span class="n">counter</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">counter</span> <span class="o">*</span> <span class="mi">2</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">counter</span><span class="p">)</span>
- <span class="k">del</span> <span class="n">x</span><span class="o">.</span><span class="n">counter</span>
- </pre></div>
- </div>
- <p>The other kind of instance attribute reference is a <em>method</em>. A method is a
- function that “belongs to” an object. (In Python, the term method is not unique
- to class instances: other object types can have methods as well. For example,
- list objects have methods called append, insert, remove, sort, and so on.
- However, in the following discussion, we’ll use the term method exclusively to
- mean methods of class instance objects, unless explicitly stated otherwise.)</p>
- <p id="index-0">Valid method names of an instance object depend on its class. By definition,
- all attributes of a class that are function objects define corresponding
- methods of its instances. So in our example, <code class="docutils literal notranslate"><span class="pre">x.f</span></code> is a valid method
- reference, since <code class="docutils literal notranslate"><span class="pre">MyClass.f</span></code> is a function, but <code class="docutils literal notranslate"><span class="pre">x.i</span></code> is not, since
- <code class="docutils literal notranslate"><span class="pre">MyClass.i</span></code> is not. But <code class="docutils literal notranslate"><span class="pre">x.f</span></code> is not the same thing as <code class="docutils literal notranslate"><span class="pre">MyClass.f</span></code> — it
- is a <em>method object</em>, not a function object.</p>
- </section>
- <section id="method-objects">
- <span id="tut-methodobjects"></span><h3><span class="section-number">9.3.4. </span>Method Objects<a class="headerlink" href="#method-objects" title="Permalink to this headline">¶</a></h3>
- <p>Usually, a method is called right after it is bound:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span><span class="o">.</span><span class="n">f</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>In the <code class="xref py py-class docutils literal notranslate"><span class="pre">MyClass</span></code> example, this will return the string <code class="docutils literal notranslate"><span class="pre">'hello</span> <span class="pre">world'</span></code>.
- However, it is not necessary to call a method right away: <code class="docutils literal notranslate"><span class="pre">x.f</span></code> is a method
- object, and can be stored away and called at a later time. For example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">xf</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">f</span>
- <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">xf</span><span class="p">())</span>
- </pre></div>
- </div>
- <p>will continue to print <code class="docutils literal notranslate"><span class="pre">hello</span> <span class="pre">world</span></code> until the end of time.</p>
- <p>What exactly happens when a method is called? You may have noticed that
- <code class="docutils literal notranslate"><span class="pre">x.f()</span></code> was called without an argument above, even though the function
- definition for <code class="xref py py-meth docutils literal notranslate"><span class="pre">f()</span></code> specified an argument. What happened to the argument?
- Surely Python raises an exception when a function that requires an argument is
- called without any — even if the argument isn’t actually used…</p>
- <p>Actually, you may have guessed the answer: the special thing about methods is
- that the instance object is passed as the first argument of the function. In our
- example, the call <code class="docutils literal notranslate"><span class="pre">x.f()</span></code> is exactly equivalent to <code class="docutils literal notranslate"><span class="pre">MyClass.f(x)</span></code>. In
- general, calling a method with a list of <em>n</em> arguments is equivalent to calling
- the corresponding function with an argument list that is created by inserting
- the method’s instance object before the first argument.</p>
- <p>If you still don’t understand how methods work, a look at the implementation can
- perhaps clarify matters. When a non-data attribute of an instance is
- referenced, the instance’s class is searched. If the name denotes a valid class
- attribute that is a function object, a method object is created by packing
- (pointers to) the instance object and the function object just found together in
- an abstract object: this is the method object. When the method object is called
- with an argument list, a new argument list is constructed from the instance
- object and the argument list, and the function object is called with this new
- argument list.</p>
- </section>
- <section id="class-and-instance-variables">
- <span id="tut-class-and-instance-variables"></span><h3><span class="section-number">9.3.5. </span>Class and Instance Variables<a class="headerlink" href="#class-and-instance-variables" title="Permalink to this headline">¶</a></h3>
- <p>Generally speaking, instance variables are for data unique to each instance
- and class variables are for attributes and methods shared by all instances
- of the class:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Dog</span><span class="p">:</span>
- <span class="n">kind</span> <span class="o">=</span> <span class="s1">'canine'</span> <span class="c1"># class variable shared by all instances</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> <span class="c1"># instance variable unique to each instance</span>
- <span class="o">>>></span> <span class="n">d</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Fido'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">e</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Buddy'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">kind</span> <span class="c1"># shared by all dogs</span>
- <span class="s1">'canine'</span>
- <span class="o">>>></span> <span class="n">e</span><span class="o">.</span><span class="n">kind</span> <span class="c1"># shared by all dogs</span>
- <span class="s1">'canine'</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">name</span> <span class="c1"># unique to d</span>
- <span class="s1">'Fido'</span>
- <span class="o">>>></span> <span class="n">e</span><span class="o">.</span><span class="n">name</span> <span class="c1"># unique to e</span>
- <span class="s1">'Buddy'</span>
- </pre></div>
- </div>
- <p>As discussed in <a class="reference internal" href="#tut-object"><span class="std std-ref">A Word About Names and Objects</span></a>, shared data can have possibly surprising
- effects with involving <a class="reference internal" href="../glossary.html#term-mutable"><span class="xref std std-term">mutable</span></a> objects such as lists and dictionaries.
- For example, the <em>tricks</em> list in the following code should not be used as a
- class variable because just a single list would be shared by all <em>Dog</em>
- instances:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Dog</span><span class="p">:</span>
- <span class="n">tricks</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># mistaken use of a class variable</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
- <span class="k">def</span> <span class="nf">add_trick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trick</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">tricks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">trick</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Fido'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">e</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Buddy'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">add_trick</span><span class="p">(</span><span class="s1">'roll over'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">e</span><span class="o">.</span><span class="n">add_trick</span><span class="p">(</span><span class="s1">'play dead'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">tricks</span> <span class="c1"># unexpectedly shared by all dogs</span>
- <span class="p">[</span><span class="s1">'roll over'</span><span class="p">,</span> <span class="s1">'play dead'</span><span class="p">]</span>
- </pre></div>
- </div>
- <p>Correct design of the class should use an instance variable instead:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Dog</span><span class="p">:</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">tricks</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># creates a new empty list for each dog</span>
- <span class="k">def</span> <span class="nf">add_trick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trick</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">tricks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">trick</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Fido'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">e</span> <span class="o">=</span> <span class="n">Dog</span><span class="p">(</span><span class="s1">'Buddy'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">add_trick</span><span class="p">(</span><span class="s1">'roll over'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">e</span><span class="o">.</span><span class="n">add_trick</span><span class="p">(</span><span class="s1">'play dead'</span><span class="p">)</span>
- <span class="o">>>></span> <span class="n">d</span><span class="o">.</span><span class="n">tricks</span>
- <span class="p">[</span><span class="s1">'roll over'</span><span class="p">]</span>
- <span class="o">>>></span> <span class="n">e</span><span class="o">.</span><span class="n">tricks</span>
- <span class="p">[</span><span class="s1">'play dead'</span><span class="p">]</span>
- </pre></div>
- </div>
- </section>
- </section>
- <section id="random-remarks">
- <span id="tut-remarks"></span><h2><span class="section-number">9.4. </span>Random Remarks<a class="headerlink" href="#random-remarks" title="Permalink to this headline">¶</a></h2>
- <p>If the same attribute name occurs in both an instance and in a class,
- then attribute lookup prioritizes the instance:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Warehouse</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">purpose</span> <span class="o">=</span> <span class="s1">'storage'</span>
- <span class="gp">... </span> <span class="n">region</span> <span class="o">=</span> <span class="s1">'west'</span>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">w1</span> <span class="o">=</span> <span class="n">Warehouse</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">w1</span><span class="o">.</span><span class="n">purpose</span><span class="p">,</span> <span class="n">w1</span><span class="o">.</span><span class="n">region</span><span class="p">)</span>
- <span class="go">storage west</span>
- <span class="gp">>>> </span><span class="n">w2</span> <span class="o">=</span> <span class="n">Warehouse</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="n">w2</span><span class="o">.</span><span class="n">region</span> <span class="o">=</span> <span class="s1">'east'</span>
- <span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">w2</span><span class="o">.</span><span class="n">purpose</span><span class="p">,</span> <span class="n">w2</span><span class="o">.</span><span class="n">region</span><span class="p">)</span>
- <span class="go">storage east</span>
- </pre></div>
- </div>
- <p>Data attributes may be referenced by methods as well as by ordinary users
- (“clients”) of an object. In other words, classes are not usable to implement
- pure abstract data types. In fact, nothing in Python makes it possible to
- enforce data hiding — it is all based upon convention. (On the other hand,
- the Python implementation, written in C, can completely hide implementation
- details and control access to an object if necessary; this can be used by
- extensions to Python written in C.)</p>
- <p>Clients should use data attributes with care — clients may mess up invariants
- maintained by the methods by stamping on their data attributes. Note that
- clients may add data attributes of their own to an instance object without
- affecting the validity of the methods, as long as name conflicts are avoided —
- again, a naming convention can save a lot of headaches here.</p>
- <p>There is no shorthand for referencing data attributes (or other methods!) from
- within methods. I find that this actually increases the readability of methods:
- there is no chance of confusing local variables and instance variables when
- glancing through a method.</p>
- <p>Often, the first argument of a method is called <code class="docutils literal notranslate"><span class="pre">self</span></code>. This is nothing more
- than a convention: the name <code class="docutils literal notranslate"><span class="pre">self</span></code> has absolutely no special meaning to
- Python. Note, however, that by not following the convention your code may be
- less readable to other Python programmers, and it is also conceivable that a
- <em>class browser</em> program might be written that relies upon such a convention.</p>
- <p>Any function object that is a class attribute defines a method for instances of
- that class. It is not necessary that the function definition is textually
- enclosed in the class definition: assigning a function object to a local
- variable in the class is also ok. For example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Function defined outside the class</span>
- <span class="k">def</span> <span class="nf">f1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
- <span class="k">return</span> <span class="nb">min</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
- <span class="n">f</span> <span class="o">=</span> <span class="n">f1</span>
- <span class="k">def</span> <span class="nf">g</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">return</span> <span class="s1">'hello world'</span>
- <span class="n">h</span> <span class="o">=</span> <span class="n">g</span>
- </pre></div>
- </div>
- <p>Now <code class="docutils literal notranslate"><span class="pre">f</span></code>, <code class="docutils literal notranslate"><span class="pre">g</span></code> and <code class="docutils literal notranslate"><span class="pre">h</span></code> are all attributes of class <code class="xref py py-class docutils literal notranslate"><span class="pre">C</span></code> that refer to
- function objects, and consequently they are all methods of instances of
- <code class="xref py py-class docutils literal notranslate"><span class="pre">C</span></code> — <code class="docutils literal notranslate"><span class="pre">h</span></code> being exactly equivalent to <code class="docutils literal notranslate"><span class="pre">g</span></code>. Note that this practice
- usually only serves to confuse the reader of a program.</p>
- <p>Methods may call other methods by using method attributes of the <code class="docutils literal notranslate"><span class="pre">self</span></code>
- argument:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Bag</span><span class="p">:</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">addtwice</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>Methods may reference global names in the same way as ordinary functions. The
- global scope associated with a method is the module containing its
- definition. (A class is never used as a global scope.) While one
- rarely encounters a good reason for using global data in a method, there are
- many legitimate uses of the global scope: for one thing, functions and modules
- imported into the global scope can be used by methods, as well as functions and
- classes defined in it. Usually, the class containing the method is itself
- defined in this global scope, and in the next section we’ll find some good
- reasons why a method would want to reference its own class.</p>
- <p>Each value is an object, and therefore has a <em>class</em> (also called its <em>type</em>).
- It is stored as <code class="docutils literal notranslate"><span class="pre">object.__class__</span></code>.</p>
- </section>
- <section id="inheritance">
- <span id="tut-inheritance"></span><h2><span class="section-number">9.5. </span>Inheritance<a class="headerlink" href="#inheritance" title="Permalink to this headline">¶</a></h2>
- <p>Of course, a language feature would not be worthy of the name “class” without
- supporting inheritance. The syntax for a derived class definition looks like
- this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">DerivedClassName</span><span class="p">(</span><span class="n">BaseClassName</span><span class="p">):</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="mi">1</span><span class="o">></span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="n">N</span><span class="o">></span>
- </pre></div>
- </div>
- <p>The name <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseClassName</span></code> must be defined in a
- namespace accessible from the scope containing the
- derived class definition. In place of a base class name, other arbitrary
- expressions are also allowed. This can be useful, for example, when the base
- class is defined in another module:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">DerivedClassName</span><span class="p">(</span><span class="n">modname</span><span class="o">.</span><span class="n">BaseClassName</span><span class="p">):</span>
- </pre></div>
- </div>
- <p>Execution of a derived class definition proceeds the same as for a base class.
- When the class object is constructed, the base class is remembered. This is
- used for resolving attribute references: if a requested attribute is not found
- in the class, the search proceeds to look in the base class. This rule is
- applied recursively if the base class itself is derived from some other class.</p>
- <p>There’s nothing special about instantiation of derived classes:
- <code class="docutils literal notranslate"><span class="pre">DerivedClassName()</span></code> creates a new instance of the class. Method references
- are resolved as follows: the corresponding class attribute is searched,
- descending down the chain of base classes if necessary, and the method reference
- is valid if this yields a function object.</p>
- <p>Derived classes may override methods of their base classes. Because methods
- have no special privileges when calling other methods of the same object, a
- method of a base class that calls another method defined in the same base class
- may end up calling a method of a derived class that overrides it. (For C++
- programmers: all methods in Python are effectively <code class="docutils literal notranslate"><span class="pre">virtual</span></code>.)</p>
- <p>An overriding method in a derived class may in fact want to extend rather than
- simply replace the base class method of the same name. There is a simple way to
- call the base class method directly: just call <code class="docutils literal notranslate"><span class="pre">BaseClassName.methodname(self,</span>
- <span class="pre">arguments)</span></code>. This is occasionally useful to clients as well. (Note that this
- only works if the base class is accessible as <code class="docutils literal notranslate"><span class="pre">BaseClassName</span></code> in the global
- scope.)</p>
- <p>Python has two built-in functions that work with inheritance:</p>
- <ul class="simple">
- <li><p>Use <a class="reference internal" href="../library/functions.html#isinstance" title="isinstance"><code class="xref py py-func docutils literal notranslate"><span class="pre">isinstance()</span></code></a> to check an instance’s type: <code class="docutils literal notranslate"><span class="pre">isinstance(obj,</span> <span class="pre">int)</span></code>
- will be <code class="docutils literal notranslate"><span class="pre">True</span></code> only if <code class="docutils literal notranslate"><span class="pre">obj.__class__</span></code> is <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a> or some class
- derived from <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a>.</p></li>
- <li><p>Use <a class="reference internal" href="../library/functions.html#issubclass" title="issubclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">issubclass()</span></code></a> to check class inheritance: <code class="docutils literal notranslate"><span class="pre">issubclass(bool,</span> <span class="pre">int)</span></code>
- is <code class="docutils literal notranslate"><span class="pre">True</span></code> since <a class="reference internal" href="../library/functions.html#bool" title="bool"><code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code></a> is a subclass of <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a>. However,
- <code class="docutils literal notranslate"><span class="pre">issubclass(float,</span> <span class="pre">int)</span></code> is <code class="docutils literal notranslate"><span class="pre">False</span></code> since <a class="reference internal" href="../library/functions.html#float" title="float"><code class="xref py py-class docutils literal notranslate"><span class="pre">float</span></code></a> is not a
- subclass of <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a>.</p></li>
- </ul>
- <section id="multiple-inheritance">
- <span id="tut-multiple"></span><h3><span class="section-number">9.5.1. </span>Multiple Inheritance<a class="headerlink" href="#multiple-inheritance" title="Permalink to this headline">¶</a></h3>
- <p>Python supports a form of multiple inheritance as well. A class definition with
- multiple base classes looks like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">DerivedClassName</span><span class="p">(</span><span class="n">Base1</span><span class="p">,</span> <span class="n">Base2</span><span class="p">,</span> <span class="n">Base3</span><span class="p">):</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="mi">1</span><span class="o">></span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o">.</span>
- <span class="o"><</span><span class="n">statement</span><span class="o">-</span><span class="n">N</span><span class="o">></span>
- </pre></div>
- </div>
- <p>For most purposes, in the simplest cases, you can think of the search for
- attributes inherited from a parent class as depth-first, left-to-right, not
- searching twice in the same class where there is an overlap in the hierarchy.
- Thus, if an attribute is not found in <code class="xref py py-class docutils literal notranslate"><span class="pre">DerivedClassName</span></code>, it is searched
- for in <code class="xref py py-class docutils literal notranslate"><span class="pre">Base1</span></code>, then (recursively) in the base classes of <code class="xref py py-class docutils literal notranslate"><span class="pre">Base1</span></code>,
- and if it was not found there, it was searched for in <code class="xref py py-class docutils literal notranslate"><span class="pre">Base2</span></code>, and so on.</p>
- <p>In fact, it is slightly more complex than that; the method resolution order
- changes dynamically to support cooperative calls to <a class="reference internal" href="../library/functions.html#super" title="super"><code class="xref py py-func docutils literal notranslate"><span class="pre">super()</span></code></a>. This
- approach is known in some other multiple-inheritance languages as
- call-next-method and is more powerful than the super call found in
- single-inheritance languages.</p>
- <p>Dynamic ordering is necessary because all cases of multiple inheritance exhibit
- one or more diamond relationships (where at least one of the parent classes
- can be accessed through multiple paths from the bottommost class). For example,
- all classes inherit from <a class="reference internal" href="../library/functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a>, so any case of multiple inheritance
- provides more than one path to reach <a class="reference internal" href="../library/functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a>. To keep the base classes
- from being accessed more than once, the dynamic algorithm linearizes the search
- order in a way that preserves the left-to-right ordering specified in each
- class, that calls each parent only once, and that is monotonic (meaning that a
- class can be subclassed without affecting the precedence order of its parents).
- Taken together, these properties make it possible to design reliable and
- extensible classes with multiple inheritance. For more detail, see
- <a class="reference external" href="https://www.python.org/download/releases/2.3/mro/">https://www.python.org/download/releases/2.3/mro/</a>.</p>
- </section>
- </section>
- <section id="private-variables">
- <span id="tut-private"></span><h2><span class="section-number">9.6. </span>Private Variables<a class="headerlink" href="#private-variables" title="Permalink to this headline">¶</a></h2>
- <p>“Private” instance variables that cannot be accessed except from inside an
- object don’t exist in Python. However, there is a convention that is followed
- by most Python code: a name prefixed with an underscore (e.g. <code class="docutils literal notranslate"><span class="pre">_spam</span></code>) should
- be treated as a non-public part of the API (whether it is a function, a method
- or a data member). It should be considered an implementation detail and subject
- to change without notice.</p>
- <p id="index-1">Since there is a valid use-case for class-private members (namely to avoid name
- clashes of names with names defined by subclasses), there is limited support for
- such a mechanism, called <em class="dfn">name mangling</em>. Any identifier of the form
- <code class="docutils literal notranslate"><span class="pre">__spam</span></code> (at least two leading underscores, at most one trailing underscore)
- is textually replaced with <code class="docutils literal notranslate"><span class="pre">_classname__spam</span></code>, where <code class="docutils literal notranslate"><span class="pre">classname</span></code> is the
- current class name with leading underscore(s) stripped. This mangling is done
- without regard to the syntactic position of the identifier, as long as it
- occurs within the definition of a class.</p>
- <p>Name mangling is helpful for letting subclasses override methods without
- breaking intraclass method calls. For example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Mapping</span><span class="p">:</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">iterable</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">items_list</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">__update</span><span class="p">(</span><span class="n">iterable</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">iterable</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">iterable</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">items_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
- <span class="n">__update</span> <span class="o">=</span> <span class="n">update</span> <span class="c1"># private copy of original update() method</span>
- <span class="k">class</span> <span class="nc">MappingSubclass</span><span class="p">(</span><span class="n">Mapping</span><span class="p">):</span>
- <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">keys</span><span class="p">,</span> <span class="n">values</span><span class="p">):</span>
- <span class="c1"># provides new signature for update()</span>
- <span class="c1"># but does not break __init__()</span>
- <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">values</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">items_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>The above example would work even if <code class="docutils literal notranslate"><span class="pre">MappingSubclass</span></code> were to introduce a
- <code class="docutils literal notranslate"><span class="pre">__update</span></code> identifier since it is replaced with <code class="docutils literal notranslate"><span class="pre">_Mapping__update</span></code> in the
- <code class="docutils literal notranslate"><span class="pre">Mapping</span></code> class and <code class="docutils literal notranslate"><span class="pre">_MappingSubclass__update</span></code> in the <code class="docutils literal notranslate"><span class="pre">MappingSubclass</span></code>
- class respectively.</p>
- <p>Note that the mangling rules are designed mostly to avoid accidents; it still is
- possible to access or modify a variable that is considered private. This can
- even be useful in special circumstances, such as in the debugger.</p>
- <p>Notice that code passed to <code class="docutils literal notranslate"><span class="pre">exec()</span></code> or <code class="docutils literal notranslate"><span class="pre">eval()</span></code> does not consider the
- classname of the invoking class to be the current class; this is similar to the
- effect of the <code class="docutils literal notranslate"><span class="pre">global</span></code> statement, the effect of which is likewise restricted
- to code that is byte-compiled together. The same restriction applies to
- <code class="docutils literal notranslate"><span class="pre">getattr()</span></code>, <code class="docutils literal notranslate"><span class="pre">setattr()</span></code> and <code class="docutils literal notranslate"><span class="pre">delattr()</span></code>, as well as when referencing
- <code class="docutils literal notranslate"><span class="pre">__dict__</span></code> directly.</p>
- </section>
- <section id="odds-and-ends">
- <span id="tut-odds"></span><h2><span class="section-number">9.7. </span>Odds and Ends<a class="headerlink" href="#odds-and-ends" title="Permalink to this headline">¶</a></h2>
- <p>Sometimes it is useful to have a data type similar to the Pascal “record” or C
- “struct”, bundling together a few named data items. The idiomatic approach
- is to use <a class="reference internal" href="../library/dataclasses.html#module-dataclasses" title="dataclasses: Generate special methods on user-defined classes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code></a> for this purpose:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
- <span class="nd">@dataclass</span>
- <span class="k">class</span> <span class="nc">Employee</span><span class="p">:</span>
- <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
- <span class="n">dept</span><span class="p">:</span> <span class="nb">str</span>
- <span class="n">salary</span><span class="p">:</span> <span class="nb">int</span>
- </pre></div>
- </div>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">john</span> <span class="o">=</span> <span class="n">Employee</span><span class="p">(</span><span class="s1">'john'</span><span class="p">,</span> <span class="s1">'computer lab'</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">john</span><span class="o">.</span><span class="n">dept</span>
- <span class="go">'computer lab'</span>
- <span class="gp">>>> </span><span class="n">john</span><span class="o">.</span><span class="n">salary</span>
- <span class="go">1000</span>
- </pre></div>
- </div>
- <p>A piece of Python code that expects a particular abstract data type can often be
- passed a class that emulates the methods of that data type instead. For
- instance, if you have a function that formats some data from a file object, you
- can define a class with methods <a class="reference internal" href="../library/io.html#io.TextIOBase.read" title="io.TextIOBase.read"><code class="xref py py-meth docutils literal notranslate"><span class="pre">read()</span></code></a> and
- <a class="reference internal" href="../library/io.html#io.TextIOBase.readline" title="io.TextIOBase.readline"><code class="xref py py-meth docutils literal notranslate"><span class="pre">readline()</span></code></a> that get the
- data from a string buffer instead, and pass it as an argument.</p>
- <p>Instance method objects have attributes, too: <code class="docutils literal notranslate"><span class="pre">m.__self__</span></code> is the instance
- object with the method <code class="xref py py-meth docutils literal notranslate"><span class="pre">m()</span></code>, and <code class="docutils literal notranslate"><span class="pre">m.__func__</span></code> is the function object
- corresponding to the method.</p>
- </section>
- <section id="iterators">
- <span id="tut-iterators"></span><h2><span class="section-number">9.8. </span>Iterators<a class="headerlink" href="#iterators" title="Permalink to this headline">¶</a></h2>
- <p>By now you have probably noticed that most container objects can be looped over
- using a <a class="reference internal" href="../reference/compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> statement:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">element</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">element</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">{</span><span class="s1">'one'</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="s1">'two'</span><span class="p">:</span><span class="mi">2</span><span class="p">}:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="s2">"123"</span><span class="p">:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"myfile.txt"</span><span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>This style of access is clear, concise, and convenient. The use of iterators
- pervades and unifies Python. Behind the scenes, the <a class="reference internal" href="../reference/compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> statement
- calls <a class="reference internal" href="../library/functions.html#iter" title="iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">iter()</span></code></a> on the container object. The function returns an iterator
- object that defines the method <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> which accesses
- elements in the container one at a time. When there are no more elements,
- <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> raises a <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> exception which tells the
- <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> loop to terminate. You can call the <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method
- using the <a class="reference internal" href="../library/functions.html#next" title="next"><code class="xref py py-func docutils literal notranslate"><span class="pre">next()</span></code></a> built-in function; this example shows how it all works:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="s1">'abc'</span>
- <span class="gp">>>> </span><span class="n">it</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">it</span>
- <span class="go"><str_iterator object at 0x10c90e650></span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">'a'</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">'b'</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">'c'</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="gt">Traceback (most recent call last):</span>
- File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
- <span class="w"> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="gr">StopIteration</span>
- </pre></div>
- </div>
- <p>Having seen the mechanics behind the iterator protocol, it is easy to add
- iterator behavior to your classes. Define an <a class="reference internal" href="../library/stdtypes.html#container.__iter__" title="container.__iter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__iter__()</span></code></a> method which
- returns an object with a <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method. If the class
- defines <code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code>, then <code class="xref py py-meth docutils literal notranslate"><span class="pre">__iter__()</span></code> can just return <code class="docutils literal notranslate"><span class="pre">self</span></code>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Reverse</span><span class="p">:</span>
- <span class="w"> </span><span class="sd">"""Iterator for looping over a sequence backwards."""</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
- <span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">return</span> <span class="bp">self</span>
- <span class="k">def</span> <span class="fm">__next__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">StopIteration</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">-</span> <span class="mi">1</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">]</span>
- </pre></div>
- </div>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">rev</span> <span class="o">=</span> <span class="n">Reverse</span><span class="p">(</span><span class="s1">'spam'</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="nb">iter</span><span class="p">(</span><span class="n">rev</span><span class="p">)</span>
- <span class="go"><__main__.Reverse object at 0x00A1DB50></span>
- <span class="gp">>>> </span><span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">rev</span><span class="p">:</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">m</span>
- <span class="go">a</span>
- <span class="go">p</span>
- <span class="go">s</span>
- </pre></div>
- </div>
- </section>
- <section id="generators">
- <span id="tut-generators"></span><h2><span class="section-number">9.9. </span>Generators<a class="headerlink" href="#generators" title="Permalink to this headline">¶</a></h2>
- <p><a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">Generators</span></a> are a simple and powerful tool for creating iterators. They
- are written like regular functions but use the <a class="reference internal" href="../reference/simple_stmts.html#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> statement
- whenever they want to return data. Each time <a class="reference internal" href="../library/functions.html#next" title="next"><code class="xref py py-func docutils literal notranslate"><span class="pre">next()</span></code></a> is called on it, the
- generator resumes where it left off (it remembers all the data values and which
- statement was last executed). An example shows that generators can be trivially
- easy to create:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">reverse</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">index</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span>
- <span class="k">yield</span> <span class="n">data</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
- </pre></div>
- </div>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">reverse</span><span class="p">(</span><span class="s1">'golf'</span><span class="p">):</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">f</span>
- <span class="go">l</span>
- <span class="go">o</span>
- <span class="go">g</span>
- </pre></div>
- </div>
- <p>Anything that can be done with generators can also be done with class-based
- iterators as described in the previous section. What makes generators so
- compact is that the <a class="reference internal" href="../library/stdtypes.html#iterator.__iter__" title="iterator.__iter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__iter__()</span></code></a> and <a class="reference internal" href="../reference/expressions.html#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> methods
- are created automatically.</p>
- <p>Another key feature is that the local variables and execution state are
- automatically saved between calls. This made the function easier to write and
- much more clear than an approach using instance variables like <code class="docutils literal notranslate"><span class="pre">self.index</span></code>
- and <code class="docutils literal notranslate"><span class="pre">self.data</span></code>.</p>
- <p>In addition to automatic method creation and saving program state, when
- generators terminate, they automatically raise <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a>. In
- combination, these features make it easy to create iterators with no more effort
- than writing a regular function.</p>
- </section>
- <section id="generator-expressions">
- <span id="tut-genexps"></span><h2><span class="section-number">9.10. </span>Generator Expressions<a class="headerlink" href="#generator-expressions" title="Permalink to this headline">¶</a></h2>
- <p>Some simple generators can be coded succinctly as expressions using a syntax
- similar to list comprehensions but with parentheses instead of square brackets.
- These expressions are designed for situations where the generator is used right
- away by an enclosing function. Generator expressions are more compact but less
- versatile than full generator definitions and tend to be more memory friendly
- than equivalent list comprehensions.</p>
- <p>Examples:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">sum</span><span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span> <span class="c1"># sum of squares</span>
- <span class="go">285</span>
- <span class="gp">>>> </span><span class="n">xvec</span> <span class="o">=</span> <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">]</span>
- <span class="gp">>>> </span><span class="n">yvec</span> <span class="o">=</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
- <span class="gp">>>> </span><span class="nb">sum</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">y</span> <span class="k">for</span> <span class="n">x</span><span class="p">,</span><span class="n">y</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">xvec</span><span class="p">,</span> <span class="n">yvec</span><span class="p">))</span> <span class="c1"># dot product</span>
- <span class="go">260</span>
- <span class="gp">>>> </span><span class="n">unique_words</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">word</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">page</span> <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
- <span class="gp">>>> </span><span class="n">valedictorian</span> <span class="o">=</span> <span class="nb">max</span><span class="p">((</span><span class="n">student</span><span class="o">.</span><span class="n">gpa</span><span class="p">,</span> <span class="n">student</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">for</span> <span class="n">student</span> <span class="ow">in</span> <span class="n">graduates</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="s1">'golf'</span>
- <span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">))</span>
- <span class="go">['f', 'l', 'o', 'g']</span>
- </pre></div>
- </div>
- <p class="rubric">Footnotes</p>
- <dl class="footnote brackets">
- <dt class="label" id="id2"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
- <dd><p>Except for one thing. Module objects have a secret read-only attribute called
- <a class="reference internal" href="../library/stdtypes.html#object.__dict__" title="object.__dict__"><code class="xref py py-attr docutils literal notranslate"><span class="pre">__dict__</span></code></a> which returns the dictionary used to implement the module’s
- namespace; the name <a class="reference internal" href="../library/stdtypes.html#object.__dict__" title="object.__dict__"><code class="xref py py-attr docutils literal notranslate"><span class="pre">__dict__</span></code></a> is an attribute but not a global name.
- Obviously, using this violates the abstraction of namespace implementation, and
- should be restricted to things like post-mortem debuggers.</p>
- </dd>
- </dl>
- </section>
- </section>
- <div class="clearer"></div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">9. Classes</a><ul>
- <li><a class="reference internal" href="#a-word-about-names-and-objects">9.1. A Word About Names and Objects</a></li>
- <li><a class="reference internal" href="#python-scopes-and-namespaces">9.2. Python Scopes and Namespaces</a><ul>
- <li><a class="reference internal" href="#scopes-and-namespaces-example">9.2.1. Scopes and Namespaces Example</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#a-first-look-at-classes">9.3. A First Look at Classes</a><ul>
- <li><a class="reference internal" href="#class-definition-syntax">9.3.1. Class Definition Syntax</a></li>
- <li><a class="reference internal" href="#class-objects">9.3.2. Class Objects</a></li>
- <li><a class="reference internal" href="#instance-objects">9.3.3. Instance Objects</a></li>
- <li><a class="reference internal" href="#method-objects">9.3.4. Method Objects</a></li>
- <li><a class="reference internal" href="#class-and-instance-variables">9.3.5. Class and Instance Variables</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#random-remarks">9.4. Random Remarks</a></li>
- <li><a class="reference internal" href="#inheritance">9.5. Inheritance</a><ul>
- <li><a class="reference internal" href="#multiple-inheritance">9.5.1. Multiple Inheritance</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#private-variables">9.6. Private Variables</a></li>
- <li><a class="reference internal" href="#odds-and-ends">9.7. Odds and Ends</a></li>
- <li><a class="reference internal" href="#iterators">9.8. Iterators</a></li>
- <li><a class="reference internal" href="#generators">9.9. Generators</a></li>
- <li><a class="reference internal" href="#generator-expressions">9.10. Generator Expressions</a></li>
- </ul>
- </li>
- </ul>
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="errors.html"
- title="previous chapter"><span class="section-number">8. </span>Errors and Exceptions</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="stdlib.html"
- title="next chapter"><span class="section-number">10. </span>Brief Tour of the Standard Library</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/tutorial/classes.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="clearer"></div>
- </div>
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- >index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="stdlib.html" title="10. Brief Tour of the Standard Library"
- >next</a> |</li>
- <li class="right" >
- <a href="errors.html" title="8. Errors and Exceptions"
- >previous</a> |</li>
- <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.0 Documentation</a> »
- </li>
- <li class="nav-item nav-item-1"><a href="index.html" >The Python Tutorial</a> »</li>
- <li class="nav-item nav-item-this"><a href=""><span class="section-number">9. </span>Classes</a></li>
- <li class="right">
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="footer">
- © <a href="../copyright.html">Copyright</a> 2001-2023, Python Software Foundation.
- <br />
- This page is licensed under the Python Software Foundation License Version 2.
- <br />
- Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
- <br />
- See <a href="/license.html">History and License</a> for more information.<br />
- <br />
- The Python Software Foundation is a non-profit corporation.
- <a href="https://www.python.org/psf/donations/">Please donate.</a>
- <br />
- <br />
- Last updated on Oct 02, 2023.
- <a href="/bugs.html">Found a bug</a>?
- <br />
- Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.5.0.
- </div>
- </body>
- </html>
|