annotate Doc/faq/programming.rst @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents ddbcb86afbdc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1 :tocdepth: 2
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
2
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
3 ===============
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
4 Programming FAQ
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
5 ===============
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
6
82986
3ae74b361f53 Closes #4159: add LaTeX tabular column specifications to tables that otherwise are cut off or have overlapping text.
Georg Brandl <georg@python.org>
parents: 81284
diff changeset
7 .. only:: html
3ae74b361f53 Closes #4159: add LaTeX tabular column specifications to tables that otherwise are cut off or have overlapping text.
Georg Brandl <georg@python.org>
parents: 81284
diff changeset
8
3ae74b361f53 Closes #4159: add LaTeX tabular column specifications to tables that otherwise are cut off or have overlapping text.
Georg Brandl <georg@python.org>
parents: 81284
diff changeset
9 .. contents::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
10
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
11 General Questions
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
12 =================
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
13
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
14 Is there a source code level debugger with breakpoints, single-stepping, etc.?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
15 ------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
16
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
17 Yes.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
18
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
19 The pdb module is a simple but adequate console-mode debugger for Python. It is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
20 part of the standard Python library, and is :mod:`documented in the Library
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
21 Reference Manual <pdb>`. You can also write your own debugger by using the code
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
22 for pdb as an example.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
23
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
24 The IDLE interactive development environment, which is part of the standard
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
25 Python distribution (normally available as Tools/scripts/idle), includes a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
26 graphical debugger. There is documentation for the IDLE debugger at
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
27 http://www.python.org/idle/doc/idle2.html#Debugger.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
28
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
29 PythonWin is a Python IDE that includes a GUI debugger based on pdb. The
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
30 Pythonwin debugger colors breakpoints and has quite a few cool features such as
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
31 debugging non-Pythonwin programs. Pythonwin is available as part of the `Python
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
32 for Windows Extensions <http://sourceforge.net/projects/pywin32/>`__ project and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
33 as a part of the ActivePython distribution (see
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
34 http://www.activestate.com/Products/ActivePython/index.html).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
35
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
36 `Boa Constructor <http://boa-constructor.sourceforge.net/>`_ is an IDE and GUI
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
37 builder that uses wxWidgets. It offers visual frame creation and manipulation,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
38 an object inspector, many views on the source like object browsers, inheritance
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
39 hierarchies, doc string generated html documentation, an advanced debugger,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
40 integrated help, and Zope support.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
41
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
42 `Eric <http://www.die-offenbachs.de/eric/index.html>`_ is an IDE built on PyQt
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
43 and the Scintilla editing component.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
44
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
45 Pydb is a version of the standard Python debugger pdb, modified for use with DDD
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
46 (Data Display Debugger), a popular graphical debugger front end. Pydb can be
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
47 found at http://bashdb.sourceforge.net/pydb/ and DDD can be found at
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
48 http://www.gnu.org/software/ddd.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
49
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
50 There are a number of commercial Python IDEs that include graphical debuggers.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
51 They include:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
52
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
53 * Wing IDE (http://wingware.com/)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
54 * Komodo IDE (http://www.activestate.com/Products/Komodo)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
55
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
56
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
57 Is there a tool to help find bugs or perform static analysis?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
58 -------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
59
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
60 Yes.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
61
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
62 PyChecker is a static analysis tool that finds bugs in Python source code and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
63 warns about code complexity and style. You can get PyChecker from
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
64 http://pychecker.sf.net.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
65
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
66 `Pylint <http://www.logilab.org/projects/pylint>`_ is another tool that checks
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
67 if a module satisfies a coding standard, and also makes it possible to write
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
68 plug-ins to add a custom feature. In addition to the bug checking that
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
69 PyChecker performs, Pylint offers some additional features such as checking line
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
70 length, whether variable names are well-formed according to your coding
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
71 standard, whether declared interfaces are fully implemented, and more.
56894
b085fd0611de Merged revisions 75797 via svnmerge from
Georg Brandl <georg@python.org>
parents: 56893
diff changeset
72 http://www.logilab.org/card/pylint_manual provides a full list of Pylint's
b085fd0611de Merged revisions 75797 via svnmerge from
Georg Brandl <georg@python.org>
parents: 56893
diff changeset
73 features.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
74
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
75
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
76 How can I create a stand-alone binary from a Python script?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
77 -----------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
78
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
79 You don't need the ability to compile Python to C code if all you want is a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
80 stand-alone program that users can download and run without having to install
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
81 the Python distribution first. There are a number of tools that determine the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
82 set of modules required by a program and bind these modules together with a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
83 Python binary to produce a single executable.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
84
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
85 One is to use the freeze tool, which is included in the Python source tree as
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
86 ``Tools/freeze``. It converts Python byte code to C arrays; a C compiler you can
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
87 embed all your modules into a new program, which is then linked with the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
88 standard Python modules.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
89
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
90 It works by scanning your source recursively for import statements (in both
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
91 forms) and looking for the modules in the standard Python path as well as in the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
92 source directory (for built-in modules). It then turns the bytecode for modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
93 written in Python into C code (array initializers that can be turned into code
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
94 objects using the marshal module) and creates a custom-made config file that
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
95 only contains those built-in modules which are actually used in the program. It
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
96 then compiles the generated C code and links it with the rest of the Python
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
97 interpreter to form a self-contained binary which acts exactly like your script.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
98
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
99 Obviously, freeze requires a C compiler. There are several other utilities
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
100 which don't. One is Thomas Heller's py2exe (Windows only) at
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
101
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
102 http://www.py2exe.org/
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
103
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
104 Another is Christian Tismer's `SQFREEZE <http://starship.python.net/crew/pirx>`_
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
105 which appends the byte code to a specially-prepared Python interpreter that can
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
106 find the byte code in the executable.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
107
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
108 Other tools include Fredrik Lundh's `Squeeze
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
109 <http://www.pythonware.com/products/python/squeeze>`_ and Anthony Tuininga's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
110 `cx_Freeze <http://starship.python.net/crew/atuining/cx_Freeze/index.html>`_.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
111
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
112
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
113 Are there coding standards or a style guide for Python programs?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
114 ----------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
115
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
116 Yes. The coding style required for standard library modules is documented as
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
117 :pep:`8`.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
118
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
119
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
120 Core Language
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
121 =============
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
122
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
123 Why am I getting an UnboundLocalError when the variable has a value?
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
124 --------------------------------------------------------------------
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
125
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
126 It can be a surprise to get the UnboundLocalError in previously working
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
127 code when it is modified by adding an assignment statement somewhere in
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
128 the body of a function.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
129
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
130 This code:
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
131
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
132 >>> x = 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
133 >>> def bar():
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
134 ... print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
135 >>> bar()
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
136 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
137
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
138 works, but this code:
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
139
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
140 >>> x = 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
141 >>> def foo():
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
142 ... print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
143 ... x += 1
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
144
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
145 results in an UnboundLocalError:
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
146
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
147 >>> foo()
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
148 Traceback (most recent call last):
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
149 ...
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
150 UnboundLocalError: local variable 'x' referenced before assignment
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
151
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
152 This is because when you make an assignment to a variable in a scope, that
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
153 variable becomes local to that scope and shadows any similarly named variable
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
154 in the outer scope. Since the last statement in foo assigns a new value to
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
155 ``x``, the compiler recognizes it as a local variable. Consequently when the
57244
7d6bad5c2d64 Merged revisions 76272 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 57242
diff changeset
156 earlier ``print(x)`` attempts to print the uninitialized local variable and
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
157 an error results.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
158
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
159 In the example above you can access the outer scope variable by declaring it
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
160 global:
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
161
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
162 >>> x = 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
163 >>> def foobar():
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
164 ... global x
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
165 ... print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
166 ... x += 1
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
167 >>> foobar()
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
168 10
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
169
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
170 This explicit declaration is required in order to remind you that (unlike the
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
171 superficially analogous situation with class and instance variables) you are
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
172 actually modifying the value of the variable in the outer scope:
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
173
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
174 >>> print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
175 11
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
176
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
177 You can do a similar thing in a nested scope using the :keyword:`nonlocal`
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
178 keyword:
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
179
57242
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
180 >>> def foo():
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
181 ... x = 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
182 ... def bar():
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
183 ... nonlocal x
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
184 ... print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
185 ... x += 1
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
186 ... bar()
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
187 ... print(x)
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
188 >>> foo()
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
189 10
3d902d67af9c Merged revisions 76270 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56894
diff changeset
190 11
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
191
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
192
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
193 What are the rules for local and global variables in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
194 ------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
195
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
196 In Python, variables that are only referenced inside a function are implicitly
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
197 global. If a variable is assigned a new value anywhere within the function's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
198 body, it's assumed to be a local. If a variable is ever assigned a new value
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
199 inside the function, the variable is implicitly local, and you need to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
200 explicitly declare it as 'global'.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
201
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
202 Though a bit surprising at first, a moment's consideration explains this. On
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
203 one hand, requiring :keyword:`global` for assigned variables provides a bar
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
204 against unintended side-effects. On the other hand, if ``global`` was required
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
205 for all global references, you'd be using ``global`` all the time. You'd have
58749
63b3a65aff52 Recorded merge of revisions 78024 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57813
diff changeset
206 to declare as global every reference to a built-in function or to a component of
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
207 an imported module. This clutter would defeat the usefulness of the ``global``
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
208 declaration for identifying side-effects.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
209
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
210
81284
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
211 Why do lambdas defined in a loop with different values all return the same result?
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
212 ----------------------------------------------------------------------------------
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
213
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
214 Assume you use a for loop to define a few different lambdas (or even plain
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
215 functions), e.g.::
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
216
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
217 >>> squares = []
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
218 >>> for x in range(5):
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
219 ... squares.append(lambda: x**2)
81284
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
220
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
221 This gives you a list that contains 5 lambdas that calculate ``x**2``. You
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
222 might expect that, when called, they would return, respectively, ``0``, ``1``,
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
223 ``4``, ``9``, and ``16``. However, when you actually try you will see that
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
224 they all return ``16``::
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
225
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
226 >>> squares[2]()
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
227 16
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
228 >>> squares[4]()
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
229 16
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
230
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
231 This happens because ``x`` is not local to the lambdas, but is defined in
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
232 the outer scope, and it is accessed when the lambda is called --- not when it
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
233 is defined. At the end of the loop, the value of ``x`` is ``4``, so all the
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
234 functions now return ``4**2``, i.e. ``16``. You can also verify this by
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
235 changing the value of ``x`` and see how the results of the lambdas change::
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
236
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
237 >>> x = 8
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
238 >>> squares[2]()
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
239 64
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
240
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
241 In order to avoid this, you need to save the values in variables local to the
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
242 lambdas, so that they don't rely on the value of the global ``x``::
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
243
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
244 >>> squares = []
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
245 >>> for x in range(5):
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
246 ... squares.append(lambda n=x: n**2)
81284
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
247
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
248 Here, ``n=x`` creates a new variable ``n`` local to the lambda and computed
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
249 when the lambda is defined so that it has the same value that ``x`` had at
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
250 that point in the loop. This means that the value of ``n`` will be ``0``
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
251 in the first lambda, ``1`` in the second, ``2`` in the third, and so on.
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
252 Therefore each lambda will now return the correct result::
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
253
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
254 >>> squares[2]()
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
255 4
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
256 >>> squares[4]()
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
257 16
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
258
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
259 Note that this behaviour is not peculiar to lambdas, but applies to regular
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
260 functions too.
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
261
02933454b7ce #13094: add Programming FAQ entry about the behavior of closures.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 81051
diff changeset
262
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
263 How do I share global variables across modules?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
264 ------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
265
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
266 The canonical way to share information across modules within a single program is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
267 to create a special module (often called config or cfg). Just import the config
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
268 module in all modules of your application; the module then becomes available as
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
269 a global name. Because there is only one instance of each module, any changes
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
270 made to the module object get reflected everywhere. For example:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
271
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
272 config.py::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
273
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
274 x = 0 # Default value of the 'x' configuration setting
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
275
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
276 mod.py::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
277
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
278 import config
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
279 config.x = 1
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
280
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
281 main.py::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
282
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
283 import config
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
284 import mod
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
285 print(config.x)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
286
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
287 Note that using a module is also the basis for implementing the Singleton design
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
288 pattern, for the same reason.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
289
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
290
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
291 What are the "best practices" for using import in a module?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
292 -----------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
293
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
294 In general, don't use ``from modulename import *``. Doing so clutters the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
295 importer's namespace. Some people avoid this idiom even with the few modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
296 that were designed to be imported in this manner. Modules designed in this
56893
70eb6a13abcd Merged revisions 75393,75416,75581,75609,75615 via svnmerge from
Georg Brandl <georg@python.org>
parents: 56890
diff changeset
297 manner include :mod:`tkinter`, and :mod:`threading`.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
298
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
299 Import modules at the top of a file. Doing so makes it clear what other modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
300 your code requires and avoids questions of whether the module name is in scope.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
301 Using one import per line makes it easy to add and delete module imports, but
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
302 using multiple imports per line uses less screen space.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
303
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
304 It's good practice if you import modules in the following order:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
305
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
306 1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
307 2. third-party library modules (anything installed in Python's site-packages
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
308 directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
309 3. locally-developed modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
310
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
311 Never use relative package imports. If you're writing code that's in the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
312 ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
313 write ``from . import m2``, even though it's legal. Write ``from package.sub
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
314 import m2`` instead. See :pep:`328` for details.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
315
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
316 It is sometimes necessary to move imports to a function or class to avoid
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
317 problems with circular imports. Gordon McMillan says:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
318
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
319 Circular imports are fine where both modules use the "import <module>" form
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
320 of import. They fail when the 2nd module wants to grab a name out of the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
321 first ("from module import name") and the import is at the top level. That's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
322 because names in the 1st are not yet available, because the first module is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
323 busy importing the 2nd.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
324
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
325 In this case, if the second module is only used in one function, then the import
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
326 can easily be moved into that function. By the time the import is called, the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
327 first module will have finished initializing, and the second module can do its
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
328 import.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
329
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
330 It may also be necessary to move imports out of the top level of code if some of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
331 the modules are platform-specific. In that case, it may not even be possible to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
332 import all of the modules at the top of the file. In this case, importing the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
333 correct modules in the corresponding platform-specific code is a good option.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
334
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
335 Only move imports into a local scope, such as inside a function definition, if
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
336 it's necessary to solve a problem such as avoiding a circular import or are
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
337 trying to reduce the initialization time of a module. This technique is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
338 especially helpful if many of the imports are unnecessary depending on how the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
339 program executes. You may also want to move imports into a function if the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
340 modules are only ever used in that function. Note that loading a module the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
341 first time may be expensive because of the one time initialization of the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
342 module, but loading a module multiple times is virtually free, costing only a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
343 couple of dictionary lookups. Even if the module name has gone out of scope,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
344 the module is probably available in :data:`sys.modules`.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
345
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
346 If only instances of a specific class use a module, then it is reasonable to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
347 import the module in the class's ``__init__`` method and then assign the module
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
348 to an instance variable so that the module is always available (via that
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
349 instance variable) during the life of the object. Note that to delay an import
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
350 until the class is instantiated, the import must be inside a method. Putting
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
351 the import inside the class but outside of any method still causes the import to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
352 occur when the module is initialized.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
353
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
354
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
355 How can I pass optional or keyword parameters from one function to another?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
356 ---------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
357
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
358 Collect the arguments using the ``*`` and ``**`` specifiers in the function's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
359 parameter list; this gives you the positional arguments as a tuple and the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
360 keyword arguments as a dictionary. You can then pass these arguments when
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
361 calling another function by using ``*`` and ``**``::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
362
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
363 def f(x, *args, **kwargs):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
364 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
365 kwargs['width'] = '14.3c'
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
366 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
367 g(x, *args, **kwargs)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
368
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
369
81051
31e1f0b7f42e Add additional links and index entries for "argument" and "parameter".
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 80615
diff changeset
370 .. index::
31e1f0b7f42e Add additional links and index entries for "argument" and "parameter".
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 80615
diff changeset
371 single: argument; difference from parameter
31e1f0b7f42e Add additional links and index entries for "argument" and "parameter".
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 80615
diff changeset
372 single: parameter; difference from argument
31e1f0b7f42e Add additional links and index entries for "argument" and "parameter".
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 80615
diff changeset
373
80615
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
374 .. _faq-argument-vs-parameter:
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
375
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
376 What is the difference between arguments and parameters?
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
377 --------------------------------------------------------
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
378
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
379 :term:`Parameters <parameter>` are defined by the names that appear in a
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
380 function definition, whereas :term:`arguments <argument>` are the values
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
381 actually passed to a function when calling it. Parameters define what types of
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
382 arguments a function can accept. For example, given the function definition::
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
383
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
384 def func(foo, bar=None, **kwargs):
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
385 pass
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
386
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
387 *foo*, *bar* and *kwargs* are parameters of ``func``. However, when calling
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
388 ``func``, for example::
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
389
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
390 func(42, bar=314, extra=somevar)
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
391
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
392 the values ``42``, ``314``, and ``somevar`` are arguments.
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
393
69d5d834c5cb Improve argument/parameter documentation (issue #15990).
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 75647
diff changeset
394
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
395 How do I write a function with output parameters (call by reference)?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
396 ---------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
397
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
398 Remember that arguments are passed by assignment in Python. Since assignment
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
399 just creates references to objects, there's no alias between an argument name in
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
400 the caller and callee, and so no call-by-reference per se. You can achieve the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
401 desired effect in a number of ways.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
402
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
403 1) By returning a tuple of the results::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
404
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
405 def func2(a, b):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
406 a = 'new-value' # a and b are local names
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
407 b = b + 1 # assigned to new objects
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
408 return a, b # return new values
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
409
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
410 x, y = 'old-value', 99
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
411 x, y = func2(x, y)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
412 print(x, y) # output: new-value 100
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
413
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
414 This is almost always the clearest solution.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
415
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
416 2) By using global variables. This isn't thread-safe, and is not recommended.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
417
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
418 3) By passing a mutable (changeable in-place) object::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
419
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
420 def func1(a):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
421 a[0] = 'new-value' # 'a' references a mutable list
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
422 a[1] = a[1] + 1 # changes a shared object
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
423
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
424 args = ['old-value', 99]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
425 func1(args)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
426 print(args[0], args[1]) # output: new-value 100
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
427
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
428 4) By passing in a dictionary that gets mutated::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
429
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
430 def func3(args):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
431 args['a'] = 'new-value' # args is a mutable dictionary
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
432 args['b'] = args['b'] + 1 # change it in-place
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
433
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
434 args = {'a':' old-value', 'b': 99}
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
435 func3(args)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
436 print(args['a'], args['b'])
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
437
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
438 5) Or bundle up values in a class instance::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
439
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
440 class callByRef:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
441 def __init__(self, **args):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
442 for (key, value) in args.items():
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
443 setattr(self, key, value)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
444
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
445 def func4(args):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
446 args.a = 'new-value' # args is a mutable callByRef
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
447 args.b = args.b + 1 # change object in-place
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
448
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
449 args = callByRef(a='old-value', b=99)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
450 func4(args)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
451 print(args.a, args.b)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
452
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
453
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
454 There's almost never a good reason to get this complicated.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
455
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
456 Your best choice is to return a tuple containing the multiple results.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
457
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
458
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
459 How do you make a higher order function in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
460 --------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
461
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
462 You have two choices: you can use nested scopes or you can use callable objects.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
463 For example, suppose you wanted to define ``linear(a,b)`` which returns a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
464 function ``f(x)`` that computes the value ``a*x+b``. Using nested scopes::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
465
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
466 def linear(a, b):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
467 def result(x):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
468 return a * x + b
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
469 return result
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
470
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
471 Or using a callable object::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
472
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
473 class linear:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
474
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
475 def __init__(self, a, b):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
476 self.a, self.b = a, b
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
477
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
478 def __call__(self, x):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
479 return self.a * x + self.b
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
480
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
481 In both cases, ::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
482
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
483 taxes = linear(0.3, 2)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
484
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
485 gives a callable object where ``taxes(10e6) == 0.3 * 10e6 + 2``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
486
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
487 The callable object approach has the disadvantage that it is a bit slower and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
488 results in slightly longer code. However, note that a collection of callables
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
489 can share their signature via inheritance::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
490
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
491 class exponential(linear):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
492 # __init__ inherited
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
493 def __call__(self, x):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
494 return self.a * (x ** self.b)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
495
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
496 Object can encapsulate state for several methods::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
497
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
498 class counter:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
499
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
500 value = 0
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
501
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
502 def set(self, x):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
503 self.value = x
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
504
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
505 def up(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
506 self.value = self.value + 1
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
507
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
508 def down(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
509 self.value = self.value - 1
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
510
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
511 count = counter()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
512 inc, dec, reset = count.up, count.down, count.set
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
513
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
514 Here ``inc()``, ``dec()`` and ``reset()`` act like functions which share the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
515 same counting variable.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
516
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
517
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
518 How do I copy an object in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
519 ----------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
520
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
521 In general, try :func:`copy.copy` or :func:`copy.deepcopy` for the general case.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
522 Not all objects can be copied, but most can.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
523
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
524 Some objects can be copied more easily. Dictionaries have a :meth:`~dict.copy`
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
525 method::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
526
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
527 newdict = olddict.copy()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
528
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
529 Sequences can be copied by slicing::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
530
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
531 new_l = l[:]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
532
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
533
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
534 How can I find the methods or attributes of an object?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
535 ------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
536
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
537 For an instance x of a user-defined class, ``dir(x)`` returns an alphabetized
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
538 list of the names containing the instance attributes and methods and attributes
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
539 defined by its class.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
540
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
541
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
542 How can my code discover the name of an object?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
543 -----------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
544
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
545 Generally speaking, it can't, because objects don't really have names.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
546 Essentially, assignment always binds a name to a value; The same is true of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
547 ``def`` and ``class`` statements, but in that case the value is a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
548 callable. Consider the following code::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
549
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
550 class A:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
551 pass
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
552
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
553 B = A
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
554
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
555 a = B()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
556 b = a
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
557 print(b)
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
558 <__main__.A object at 0x16D07CC>
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
559 print(a)
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
560 <__main__.A object at 0x16D07CC>
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
561
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
562 Arguably the class has a name: even though it is bound to two names and invoked
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
563 through the name B the created instance is still reported as an instance of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
564 class A. However, it is impossible to say whether the instance's name is a or
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
565 b, since both names are bound to the same value.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
566
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
567 Generally speaking it should not be necessary for your code to "know the names"
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
568 of particular values. Unless you are deliberately writing introspective
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
569 programs, this is usually an indication that a change of approach might be
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
570 beneficial.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
571
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
572 In comp.lang.python, Fredrik Lundh once gave an excellent analogy in answer to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
573 this question:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
574
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
575 The same way as you get the name of that cat you found on your porch: the cat
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
576 (object) itself cannot tell you its name, and it doesn't really care -- so
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
577 the only way to find out what it's called is to ask all your neighbours
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
578 (namespaces) if it's their cat (object)...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
579
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
580 ....and don't be surprised if you'll find that it's known by many names, or
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
581 no name at all!
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
582
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
583
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
584 What's up with the comma operator's precedence?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
585 -----------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
586
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
587 Comma is not an operator in Python. Consider this session::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
588
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
589 >>> "a" in "b", "a"
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
590 (False, 'a')
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
591
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
592 Since the comma is not an operator, but a separator between expressions the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
593 above is evaluated as if you had entered::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
594
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
595 ("a" in "b"), "a"
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
596
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
597 not::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
598
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
599 "a" in ("b", "a")
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
600
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
601 The same is true of the various assignment operators (``=``, ``+=`` etc). They
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
602 are not truly operators but syntactic delimiters in assignment statements.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
603
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
604
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
605 Is there an equivalent of C's "?:" ternary operator?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
606 ----------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
607
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
608 Yes, there is. The syntax is as follows::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
609
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
610 [on_true] if [expression] else [on_false]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
611
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
612 x, y = 50, 25
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
613 small = x if x < y else y
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
614
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
615 Before this syntax was introduced in Python 2.5, a common idiom was to use
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
616 logical operators::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
617
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
618 [expression] and [on_true] or [on_false]
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
619
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
620 However, this idiom is unsafe, as it can give wrong results when *on_true*
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
621 has a false boolean value. Therefore, it is always better to use
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
622 the ``... if ... else ...`` form.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
623
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
624
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
625 Is it possible to write obfuscated one-liners in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
626 --------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
627
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
628 Yes. Usually this is done by nesting :keyword:`lambda` within
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
629 :keyword:`lambda`. See the following three examples, due to Ulf Bartelt::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
630
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
631 from functools import reduce
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
632
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
633 # Primes < 1000
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
634 print(list(filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
635 map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))))
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
636
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
637 # First 10 Fibonacci numbers
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
638 print(list(map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1:
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
639 f(x,f), range(10))))
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
640
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
641 # Mandelbrot set
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
642 print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
643 Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
644 Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
645 i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
646 >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
647 64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
648 ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24))
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
649 # \___ ___/ \___ ___/ | | |__ lines on screen
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
650 # V V | |______ columns on screen
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
651 # | | |__________ maximum of "iterations"
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
652 # | |_________________ range on y axis
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
653 # |____________________________ range on x axis
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
654
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
655 Don't try this at home, kids!
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
656
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
657
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
658 Numbers and strings
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
659 ===================
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
660
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
661 How do I specify hexadecimal and octal integers?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
662 ------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
663
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
664 To specify an octal digit, precede the octal value with a zero, and then a lower
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
665 or uppercase "o". For example, to set the variable "a" to the octal value "10"
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
666 (8 in decimal), type::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
667
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
668 >>> a = 0o10
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
669 >>> a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
670 8
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
671
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
672 Hexadecimal is just as easy. Simply precede the hexadecimal number with a zero,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
673 and then a lower or uppercase "x". Hexadecimal digits can be specified in lower
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
674 or uppercase. For example, in the Python interpreter::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
675
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
676 >>> a = 0xa5
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
677 >>> a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
678 165
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
679 >>> b = 0XB2
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
680 >>> b
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
681 178
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
682
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
683
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
684 Why does -22 // 10 return -3?
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
685 -----------------------------
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
686
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
687 It's primarily driven by the desire that ``i % j`` have the same sign as ``j``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
688 If you want that, and also want::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
689
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
690 i == (i // j) * j + (i % j)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
691
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
692 then integer division has to return the floor. C also requires that identity to
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
693 hold, and then compilers that truncate ``i // j`` need to make ``i % j`` have
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
694 the same sign as ``i``.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
695
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
696 There are few real use cases for ``i % j`` when ``j`` is negative. When ``j``
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
697 is positive, there are many, and in virtually all of them it's more useful for
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
698 ``i % j`` to be ``>= 0``. If the clock says 10 now, what did it say 200 hours
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
699 ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
700 bite.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
701
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
702
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
703 How do I convert a string to a number?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
704 --------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
705
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
706 For integers, use the built-in :func:`int` type constructor, e.g. ``int('144')
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
707 == 144``. Similarly, :func:`float` converts to floating-point,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
708 e.g. ``float('144') == 144.0``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
709
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
710 By default, these interpret the number as decimal, so that ``int('0144') ==
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
711 144`` and ``int('0x144')`` raises :exc:`ValueError`. ``int(string, base)`` takes
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
712 the base to convert from as a second optional argument, so ``int('0x144', 16) ==
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
713 324``. If the base is specified as 0, the number is interpreted using Python's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
714 rules: a leading '0' indicates octal, and '0x' indicates a hex number.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
715
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
716 Do not use the built-in function :func:`eval` if all you need is to convert
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
717 strings to numbers. :func:`eval` will be significantly slower and it presents a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
718 security risk: someone could pass you a Python expression that might have
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
719 unwanted side effects. For example, someone could pass
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
720 ``__import__('os').system("rm -rf $HOME")`` which would erase your home
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
721 directory.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
722
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
723 :func:`eval` also has the effect of interpreting numbers as Python expressions,
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
724 so that e.g. ``eval('09')`` gives a syntax error because Python does not allow
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
725 leading '0' in a decimal number (except '0').
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
726
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
727
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
728 How do I convert a number to a string?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
729 --------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
730
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
731 To convert, e.g., the number 144 to the string '144', use the built-in type
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
732 constructor :func:`str`. If you want a hexadecimal or octal representation, use
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
733 the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
734 the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
735 ``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
736
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
737
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
738 How do I modify a string in place?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
739 ----------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
740
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
741 You can't, because strings are immutable. In most situations, you should
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
742 simply construct a new string from the various parts you want to assemble
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
743 it from. However, if you need an object with the ability to modify in-place
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
744 unicode data, try using a :class:`io.StringIO` object or the :mod:`array`
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
745 module::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
746
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
747 >>> import io
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
748 >>> s = "Hello, world"
73834
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
749 >>> sio = io.StringIO(s)
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
750 >>> sio.getvalue()
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
751 'Hello, world'
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
752 >>> sio.seek(7)
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
753 7
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
754 >>> sio.write("there!")
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
755 6
140b8c98c7b9 Streamline FAQ entry about the ternary operator, and suggest using io.StringIO for a mutable unicode container.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73832
diff changeset
756 >>> sio.getvalue()
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
757 'Hello, there!'
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
758
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
759 >>> import array
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
760 >>> a = array.array('u', s)
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
761 >>> print(a)
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
762 array('u', 'Hello, world')
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
763 >>> a[0] = 'y'
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
764 >>> print(a)
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
765 array('u', 'yello, world')
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
766 >>> a.tounicode()
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
767 'yello, world'
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
768
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
769
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
770 How do I use strings to call functions/methods?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
771 -----------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
772
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
773 There are various techniques.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
774
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
775 * The best is to use a dictionary that maps strings to functions. The primary
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
776 advantage of this technique is that the strings do not need to match the names
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
777 of the functions. This is also the primary technique used to emulate a case
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
778 construct::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
779
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
780 def a():
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
781 pass
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
782
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
783 def b():
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
784 pass
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
785
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
786 dispatch = {'go': a, 'stop': b} # Note lack of parens for funcs
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
787
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
788 dispatch[get_input()]() # Note trailing parens to call function
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
789
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
790 * Use the built-in function :func:`getattr`::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
791
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
792 import foo
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
793 getattr(foo, 'bar')()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
794
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
795 Note that :func:`getattr` works on any object, including classes, class
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
796 instances, modules, and so on.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
797
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
798 This is used in several places in the standard library, like this::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
799
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
800 class Foo:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
801 def do_foo(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
802 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
803
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
804 def do_bar(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
805 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
806
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
807 f = getattr(foo_instance, 'do_' + opname)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
808 f()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
809
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
810
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
811 * Use :func:`locals` or :func:`eval` to resolve the function name::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
812
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
813 def myFunc():
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
814 print("hello")
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
815
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
816 fname = "myFunc"
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
817
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
818 f = locals()[fname]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
819 f()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
820
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
821 f = eval(fname)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
822 f()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
823
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
824 Note: Using :func:`eval` is slow and dangerous. If you don't have absolute
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
825 control over the contents of the string, someone could pass a string that
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
826 resulted in an arbitrary function being executed.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
827
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
828 Is there an equivalent to Perl's chomp() for removing trailing newlines from strings?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
829 -------------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
830
73836
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
831 You can use ``S.rstrip("\r\n")`` to remove all occurrences of any line
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
832 terminator from the end of the string ``S`` without removing other trailing
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
833 whitespace. If the string ``S`` represents more than one line, with several
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
834 empty lines at the end, the line terminators for all the blank lines will
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
835 be removed::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
836
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
837 >>> lines = ("line 1 \r\n"
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
838 ... "\r\n"
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
839 ... "\r\n")
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
840 >>> lines.rstrip("\n\r")
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
841 'line 1 '
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
842
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
843 Since this is typically only desired when reading text one line at a time, using
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
844 ``S.rstrip()`` this way works well.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
845
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
846
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
847 Is there a scanf() or sscanf() equivalent?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
848 ------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
849
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
850 Not as such.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
851
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
852 For simple input parsing, the easiest approach is usually to split the line into
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
853 whitespace-delimited words using the :meth:`~str.split` method of string objects
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
854 and then convert decimal strings to numeric values using :func:`int` or
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
855 :func:`float`. ``split()`` supports an optional "sep" parameter which is useful
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
856 if the line uses something other than whitespace as a separator.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
857
64901
96e7ee232abf #9582 - add a missing "are" and reflow the line.
Brian Curtin <brian.curtin@gmail.com>
parents: 64875
diff changeset
858 For more complicated input parsing, regular expressions are more powerful
65137
521eac31a893 Migrate to Sphinx 1.0 C language constructs.
Georg Brandl <georg@python.org>
parents: 64901
diff changeset
859 than C's :c:func:`sscanf` and better suited for the task.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
860
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
861
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
862 What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean?
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
863 -------------------------------------------------------------------
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
864
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
865 See the :ref:`unicode-howto`.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
866
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
867
73908
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
868 Performance
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
869 ===========
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
870
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
871 My program is too slow. How do I speed it up?
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
872 ---------------------------------------------
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
873
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
874 That's a tough one, in general. First, here are a list of things to
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
875 remember before diving further:
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
876
75647
0092ab03fdd5 Closes #14305: fix typo.
Georg Brandl <georg@python.org>
parents: 73908
diff changeset
877 * Performance characteristics vary across Python implementations. This FAQ
73908
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
878 focusses on :term:`CPython`.
75647
0092ab03fdd5 Closes #14305: fix typo.
Georg Brandl <georg@python.org>
parents: 73908
diff changeset
879 * Behaviour can vary across operating systems, especially when talking about
73908
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
880 I/O or multi-threading.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
881 * You should always find the hot spots in your program *before* attempting to
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
882 optimize any code (see the :mod:`profile` module).
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
883 * Writing benchmark scripts will allow you to iterate quickly when searching
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
884 for improvements (see the :mod:`timeit` module).
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
885 * It is highly recommended to have good code coverage (through unit testing
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
886 or any other technique) before potentially introducing regressions hidden
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
887 in sophisticated optimizations.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
888
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
889 That being said, there are many tricks to speed up Python code. Here are
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
890 some general principles which go a long way towards reaching acceptable
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
891 performance levels:
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
892
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
893 * Making your algorithms faster (or changing to faster ones) can yield
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
894 much larger benefits than trying to sprinkle micro-optimization tricks
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
895 all over your code.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
896
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
897 * Use the right data structures. Study documentation for the :ref:`bltin-types`
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
898 and the :mod:`collections` module.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
899
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
900 * When the standard library provides a primitive for doing something, it is
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
901 likely (although not guaranteed) to be faster than any alternative you
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
902 may come up with. This is doubly true for primitives written in C, such
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
903 as builtins and some extension types. For example, be sure to use
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
904 either the :meth:`list.sort` built-in method or the related :func:`sorted`
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
905 function to do sorting (and see the
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
906 `sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
907 of moderately advanced usage).
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
908
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
909 * Abstractions tend to create indirections and force the interpreter to work
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
910 more. If the levels of indirection outweigh the amount of useful work
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
911 done, your program will be slower. You should avoid excessive abstraction,
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
912 especially under the form of tiny functions or methods (which are also often
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
913 detrimental to readability).
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
914
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
915 If you have reached the limit of what pure Python can allow, there are tools
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
916 to take you further away. For example, `Cython <http://cython.org>`_ can
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
917 compile a slightly modified version of Python code into a C extension, and
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
918 can be used on many different platforms. Cython can take advantage of
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
919 compilation (and optional type annotations) to make your code significantly
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
920 faster than when interpreted. If you are confident in your C programming
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
921 skills, you can also :ref:`write a C extension module <extending-index>`
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
922 yourself.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
923
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
924 .. seealso::
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
925 The wiki page devoted to `performance tips
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
926 <http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_.
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
927
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
928 .. _efficient_string_concatenation:
eb30f2becb79 Issue #13528: rework the performance question in the programming FAQ
Antoine Pitrou <solipsis@pitrou.net>
parents: 73836
diff changeset
929
73735
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
930 What is the most efficient way to concatenate many strings together?
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
931 --------------------------------------------------------------------
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
932
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
933 :class:`str` and :class:`bytes` objects are immutable, therefore concatenating
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
934 many strings together is inefficient as each concatenation creates a new
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
935 object. In the general case, the total runtime cost is quadratic in the
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
936 total string length.
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
937
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
938 To accumulate many :class:`str` objects, the recommended idiom is to place
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
939 them into a list and call :meth:`str.join` at the end::
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
940
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
941 chunks = []
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
942 for s in my_strings:
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
943 chunks.append(s)
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
944 result = ''.join(chunks)
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
945
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
946 (another reasonably efficient idiom is to use :class:`io.StringIO`)
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
947
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
948 To accumulate many :class:`bytes` objects, the recommended idiom is to extend
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
949 a :class:`bytearray` object using in-place concatenation (the ``+=`` operator)::
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
950
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
951 result = bytearray()
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
952 for b in my_bytes_objects:
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
953 result += b
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
954
2d6f0e2fe034 Clarify concatenation behaviour of immutable strings, and remove explicit
Antoine Pitrou <solipsis@pitrou.net>
parents: 72177
diff changeset
955
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
956 Sequences (Tuples/Lists)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
957 ========================
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
958
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
959 How do I convert between tuples and lists?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
960 ------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
961
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
962 The type constructor ``tuple(seq)`` converts any sequence (actually, any
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
963 iterable) into a tuple with the same items in the same order.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
964
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
965 For example, ``tuple([1, 2, 3])`` yields ``(1, 2, 3)`` and ``tuple('abc')``
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
966 yields ``('a', 'b', 'c')``. If the argument is a tuple, it does not make a copy
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
967 but returns the same object, so it is cheap to call :func:`tuple` when you
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
968 aren't sure that an object is already a tuple.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
969
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
970 The type constructor ``list(seq)`` converts any sequence or iterable into a list
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
971 with the same items in the same order. For example, ``list((1, 2, 3))`` yields
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
972 ``[1, 2, 3]`` and ``list('abc')`` yields ``['a', 'b', 'c']``. If the argument
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
973 is a list, it makes a copy just like ``seq[:]`` would.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
974
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
975
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
976 What's a negative index?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
977 ------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
978
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
979 Python sequences are indexed with positive numbers and negative numbers. For
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
980 positive numbers 0 is the first index 1 is the second index and so forth. For
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
981 negative indices -1 is the last index and -2 is the penultimate (next to last)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
982 index and so forth. Think of ``seq[-n]`` as the same as ``seq[len(seq)-n]``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
983
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
984 Using negative indices can be very convenient. For example ``S[:-1]`` is all of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
985 the string except for its last character, which is useful for removing the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
986 trailing newline from a string.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
987
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
988
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
989 How do I iterate over a sequence in reverse order?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
990 --------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
991
58749
63b3a65aff52 Recorded merge of revisions 78024 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57813
diff changeset
992 Use the :func:`reversed` built-in function, which is new in Python 2.4::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
993
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
994 for x in reversed(sequence):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
995 ... # do something with x...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
996
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
997 This won't touch your original sequence, but build a new copy with reversed
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
998 order to iterate over.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
999
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1000 With Python 2.3, you can use an extended slice syntax::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1001
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1002 for x in sequence[::-1]:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1003 ... # do something with x...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1004
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1005
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1006 How do you remove duplicates from a list?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1007 -----------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1008
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1009 See the Python Cookbook for a long discussion of many ways to do this:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1010
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1011 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1012
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1013 If you don't mind reordering the list, sort it and then scan from the end of the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1014 list, deleting duplicates as you go::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1015
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1016 if mylist:
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1017 mylist.sort()
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1018 last = mylist[-1]
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1019 for i in range(len(mylist)-2, -1, -1):
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1020 if last == mylist[i]:
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1021 del mylist[i]
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1022 else:
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1023 last = mylist[i]
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1024
73836
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
1025 If all elements of the list may be used as set keys (i.e. they are all
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
1026 :term:`hashable`) this is often faster ::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1027
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1028 mylist = list(set(mylist))
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1029
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1030 This converts the list into a set, thereby removing duplicates, and then back
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1031 into a list.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1032
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1033
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1034 How do you make an array in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1035 -----------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1036
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1037 Use a list::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1038
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1039 ["this", 1, "is", "an", "array"]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1040
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1041 Lists are equivalent to C or Pascal arrays in their time complexity; the primary
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1042 difference is that a Python list can contain objects of many different types.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1043
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1044 The ``array`` module also provides methods for creating arrays of fixed types
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1045 with compact representations, but they are slower to index than lists. Also
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1046 note that the Numeric extensions and others define array-like structures with
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1047 various characteristics as well.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1048
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1049 To get Lisp-style linked lists, you can emulate cons cells using tuples::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1050
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1051 lisp_list = ("like", ("this", ("example", None) ) )
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1052
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1053 If mutability is desired, you could use lists instead of tuples. Here the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1054 analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1055 ``lisp_list[1]``. Only do this if you're sure you really need to, because it's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1056 usually a lot slower than using Python lists.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1057
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1058
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1059 How do I create a multidimensional list?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1060 ----------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1061
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1062 You probably tried to make a multidimensional array like this::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1063
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1064 >>> A = [[None] * 2] * 3
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1065
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1066 This looks correct if you print it::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1067
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1068 >>> A
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1069 [[None, None], [None, None], [None, None]]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1070
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1071 But when you assign a value, it shows up in multiple places:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1072
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1073 >>> A[0][0] = 5
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1074 >>> A
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1075 [[5, None], [5, None], [5, None]]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1076
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1077 The reason is that replicating a list with ``*`` doesn't create copies, it only
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1078 creates references to the existing objects. The ``*3`` creates a list
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1079 containing 3 references to the same list of length two. Changes to one row will
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1080 show in all rows, which is almost certainly not what you want.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1081
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1082 The suggested approach is to create a list of the desired length first and then
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1083 fill in each element with a newly created list::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1084
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1085 A = [None] * 3
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1086 for i in range(3):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1087 A[i] = [None] * 2
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1088
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1089 This generates a list containing 3 different lists of length two. You can also
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1090 use a list comprehension::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1091
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1092 w, h = 2, 3
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1093 A = [[None] * w for i in range(h)]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1094
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1095 Or, you can use an extension that provides a matrix datatype; `Numeric Python
84061
aafa11c1dd61 #18126: update NumPy links in the documentation. Patch by Yury V. Zaytsev.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 83882
diff changeset
1096 <http://www.numpy.org/>`_ is the best known.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1097
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1098
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1099 How do I apply a method to a sequence of objects?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1100 -------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1101
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1102 Use a list comprehension::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1103
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1104 result = [obj.method() for obj in mylist]
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1105
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1106
83860
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1107 Why does a_tuple[i] += ['item'] raise an exception when the addition works?
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1108 ---------------------------------------------------------------------------
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1109
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1110 This is because of a combination of the fact that augmented assignment
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1111 operators are *assignment* operators, and the difference between mutable and
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1112 immutable objects in Python.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1113
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1114 This discussion applies in general when augmented assignment operators are
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1115 applied to elements of a tuple that point to mutable objects, but we'll use
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1116 a ``list`` and ``+=`` as our exemplar.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1117
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1118 If you wrote::
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1119
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1120 >>> a_tuple = (1, 2)
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1121 >>> a_tuple[0] += 1
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1122 Traceback (most recent call last):
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1123 ...
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1124 TypeError: 'tuple' object does not support item assignment
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1125
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1126 The reason for the exception should be immediately clear: ``1`` is added to the
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1127 object ``a_tuple[0]`` points to (``1``), producing the result object, ``2``,
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1128 but when we attempt to assign the result of the computation, ``2``, to element
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1129 ``0`` of the tuple, we get an error because we can't change what an element of
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1130 a tuple points to.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1131
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1132 Under the covers, what this augmented assignment statement is doing is
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1133 approximately this::
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1134
83882
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1135 >>> result = a_tuple[0] + 1
83860
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1136 >>> a_tuple[0] = result
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1137 Traceback (most recent call last):
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1138 ...
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1139 TypeError: 'tuple' object does not support item assignment
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1140
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1141 It is the assignment part of the operation that produces the error, since a
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1142 tuple is immutable.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1143
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1144 When you write something like::
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1145
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1146 >>> a_tuple = (['foo'], 'bar')
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1147 >>> a_tuple[0] += ['item']
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1148 Traceback (most recent call last):
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1149 ...
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1150 TypeError: 'tuple' object does not support item assignment
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1151
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1152 The exception is a bit more surprising, and even more surprising is the fact
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1153 that even though there was an error, the append worked::
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1154
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1155 >>> a_tuple[0]
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1156 ['foo', 'item']
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1157
83882
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1158 To see why this happens, you need to know that (a) if an object implements an
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1159 ``__iadd__`` magic method, it gets called when the ``+=`` augmented assignment
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1160 is executed, and its return value is what gets used in the assignment statement;
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1161 and (b) for lists, ``__iadd__`` is equivalent to calling ``extend`` on the list
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1162 and returning the list. That's why we say that for lists, ``+=`` is a
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1163 "shorthand" for ``list.extend``::
83860
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1164
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1165 >>> a_list = []
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1166 >>> a_list += [1]
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1167 >>> a_list
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1168 [1]
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1169
83882
6ab88d6527f1 #17973: fix technical inaccuracy in faq entry (it now passes doctest).
R David Murray <rdmurray@bitdance.com>
parents: 83860
diff changeset
1170 This is equivalent to::
83860
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1171
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1172 >>> result = a_list.__iadd__([1])
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1173 >>> a_list = result
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1174
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1175 The object pointed to by a_list has been mutated, and the pointer to the
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1176 mutated object is assigned back to ``a_list``. The end result of the
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1177 assignment is a no-op, since it is a pointer to the same object that ``a_list``
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1178 was previously pointing to, but the assignment still happens.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1179
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1180 Thus, in our tuple example what is happening is equivalent to::
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1181
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1182 >>> result = a_tuple[0].__iadd__(['item'])
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1183 >>> a_tuple[0] = result
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1184 Traceback (most recent call last):
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1185 ...
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1186 TypeError: 'tuple' object does not support item assignment
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1187
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1188 The ``__iadd__`` succeeds, and thus the list is extended, but even though
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1189 ``result`` points to the same object that ``a_tuple[0]`` already points to,
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1190 that final assignment still results in an error, because tuples are immutable.
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1191
b363473cfe9c #17973: Add FAQ entry for ([],)[0] += [1] both extending and raising.
R David Murray <rdmurray@bitdance.com>
parents: 82986
diff changeset
1192
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1193 Dictionaries
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1194 ============
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1195
87607
22e514e41fac recommend OrderedDict for this FAQ (closes #19805)
Benjamin Peterson <benjamin@python.org>
parents: 86230
diff changeset
1196 How can I get a dictionary to store and display its keys in a consistent order?
22e514e41fac recommend OrderedDict for this FAQ (closes #19805)
Benjamin Peterson <benjamin@python.org>
parents: 86230
diff changeset
1197 -------------------------------------------------------------------------------
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1198
87607
22e514e41fac recommend OrderedDict for this FAQ (closes #19805)
Benjamin Peterson <benjamin@python.org>
parents: 86230
diff changeset
1199 Use :class:`collections.OrderedDict`.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1200
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1201 I want to do a complicated sort: can you do a Schwartzian Transform in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1202 ------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1203
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1204 The technique, attributed to Randal Schwartz of the Perl community, sorts the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1205 elements of a list by a metric which maps each element to its "sort value". In
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1206 Python, just use the ``key`` argument for the ``sort()`` method::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1207
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1208 Isorted = L[:]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1209 Isorted.sort(key=lambda s: int(s[10:15]))
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1210
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1211 The ``key`` argument is new in Python 2.4, for older versions this kind of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1212 sorting is quite simple to do with list comprehensions. To sort a list of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1213 strings by their uppercase values::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1214
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1215 tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1216 tmp1.sort()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1217 Usorted = [x[1] for x in tmp1]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1218
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1219 To sort by the integer value of a subfield extending from positions 10-15 in
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1220 each string::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1221
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1222 tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1223 tmp2.sort()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1224 Isorted = [x[1] for x in tmp2]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1225
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1226 For versions prior to 3.0, Isorted may also be computed by ::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1227
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1228 def intfield(s):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1229 return int(s[10:15])
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1230
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1231 def Icmp(s1, s2):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1232 return cmp(intfield(s1), intfield(s2))
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1233
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1234 Isorted = L[:]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1235 Isorted.sort(Icmp)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1236
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1237 but since this method calls ``intfield()`` many times for each element of L, it
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1238 is slower than the Schwartzian Transform.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1239
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1240
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1241 How can I sort one list by values from another list?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1242 ----------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1243
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1244 Merge them into an iterator of tuples, sort the resulting list, and then pick
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1245 out the element you want. ::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1246
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1247 >>> list1 = ["what", "I'm", "sorting", "by"]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1248 >>> list2 = ["something", "else", "to", "sort"]
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1249 >>> pairs = zip(list1, list2)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1250 >>> pairs = sorted(pairs)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1251 >>> pairs
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1252 [("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1253 >>> result = [x[1] for x in pairs]
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1254 >>> result
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1255 ['else', 'sort', 'to', 'something']
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1256
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1257
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1258 An alternative for the last step is::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1259
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1260 >>> result = []
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1261 >>> for p in pairs: result.append(p[1])
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1262
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1263 If you find this more legible, you might prefer to use this instead of the final
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1264 list comprehension. However, it is almost twice as slow for long lists. Why?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1265 First, the ``append()`` operation has to reallocate memory, and while it uses
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1266 some tricks to avoid doing that each time, it still has to do it occasionally,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1267 and that costs quite a bit. Second, the expression "result.append" requires an
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1268 extra attribute lookup, and third, there's a speed reduction from having to make
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1269 all those function calls.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1270
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1271
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1272 Objects
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1273 =======
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1274
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1275 What is a class?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1276 ----------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1277
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1278 A class is the particular object type created by executing a class statement.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1279 Class objects are used as templates to create instance objects, which embody
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1280 both the data (attributes) and code (methods) specific to a datatype.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1281
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1282 A class can be based on one or more other classes, called its base class(es). It
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1283 then inherits the attributes and methods of its base classes. This allows an
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1284 object model to be successively refined by inheritance. You might have a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1285 generic ``Mailbox`` class that provides basic accessor methods for a mailbox,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1286 and subclasses such as ``MboxMailbox``, ``MaildirMailbox``, ``OutlookMailbox``
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1287 that handle various specific mailbox formats.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1288
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1289
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1290 What is a method?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1291 -----------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1292
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1293 A method is a function on some object ``x`` that you normally call as
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1294 ``x.name(arguments...)``. Methods are defined as functions inside the class
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1295 definition::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1296
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1297 class C:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1298 def meth (self, arg):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1299 return arg * 2 + self.attribute
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1300
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1301
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1302 What is self?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1303 -------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1304
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1305 Self is merely a conventional name for the first argument of a method. A method
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1306 defined as ``meth(self, a, b, c)`` should be called as ``x.meth(a, b, c)`` for
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1307 some instance ``x`` of the class in which the definition occurs; the called
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1308 method will think it is called as ``meth(x, a, b, c)``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1309
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1310 See also :ref:`why-self`.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1311
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1312
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1313 How do I check if an object is an instance of a given class or of a subclass of it?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1314 -----------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1315
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1316 Use the built-in function ``isinstance(obj, cls)``. You can check if an object
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1317 is an instance of any of a number of classes by providing a tuple instead of a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1318 single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1319 check whether an object is one of Python's built-in types, e.g.
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1320 ``isinstance(obj, str)`` or ``isinstance(obj, (int, float, complex))``.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1321
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1322 Note that most programs do not use :func:`isinstance` on user-defined classes
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1323 very often. If you are developing the classes yourself, a more proper
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1324 object-oriented style is to define methods on the classes that encapsulate a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1325 particular behaviour, instead of checking the object's class and doing a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1326 different thing based on what class it is. For example, if you have a function
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1327 that does something::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1328
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1329 def search(obj):
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1330 if isinstance(obj, Mailbox):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1331 # ... code to search a mailbox
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1332 elif isinstance(obj, Document):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1333 # ... code to search a document
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1334 elif ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1335
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1336 A better approach is to define a ``search()`` method on all the classes and just
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1337 call it::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1338
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1339 class Mailbox:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1340 def search(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1341 # ... code to search a mailbox
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1342
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1343 class Document:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1344 def search(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1345 # ... code to search a document
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1346
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1347 obj.search()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1348
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1349
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1350 What is delegation?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1351 -------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1352
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1353 Delegation is an object oriented technique (also called a design pattern).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1354 Let's say you have an object ``x`` and want to change the behaviour of just one
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1355 of its methods. You can create a new class that provides a new implementation
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1356 of the method you're interested in changing and delegates all other methods to
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1357 the corresponding method of ``x``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1358
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1359 Python programmers can easily implement delegation. For example, the following
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1360 class implements a class that behaves like a file but converts all written data
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1361 to uppercase::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1362
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1363 class UpperOut:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1364
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1365 def __init__(self, outfile):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1366 self._outfile = outfile
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1367
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1368 def write(self, s):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1369 self._outfile.write(s.upper())
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1370
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1371 def __getattr__(self, name):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1372 return getattr(self._outfile, name)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1373
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1374 Here the ``UpperOut`` class redefines the ``write()`` method to convert the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1375 argument string to uppercase before calling the underlying
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1376 ``self.__outfile.write()`` method. All other methods are delegated to the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1377 underlying ``self.__outfile`` object. The delegation is accomplished via the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1378 ``__getattr__`` method; consult :ref:`the language reference <attribute-access>`
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1379 for more information about controlling attribute access.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1380
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1381 Note that for more general cases delegation can get trickier. When attributes
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1382 must be set as well as retrieved, the class must define a :meth:`__setattr__`
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1383 method too, and it must do so carefully. The basic implementation of
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1384 :meth:`__setattr__` is roughly equivalent to the following::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1385
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1386 class X:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1387 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1388 def __setattr__(self, name, value):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1389 self.__dict__[name] = value
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1390 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1391
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1392 Most :meth:`__setattr__` implementations must modify ``self.__dict__`` to store
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1393 local state for self without causing an infinite recursion.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1394
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1395
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1396 How do I call a method defined in a base class from a derived class that overrides it?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1397 --------------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1398
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1399 Use the built-in :func:`super` function::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1400
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1401 class Derived(Base):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1402 def meth (self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1403 super(Derived, self).meth()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1404
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1405 For version prior to 3.0, you may be using classic classes: For a class
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1406 definition such as ``class Derived(Base): ...`` you can call method ``meth()``
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1407 defined in ``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self,
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1408 arguments...)``. Here, ``Base.meth`` is an unbound method, so you need to
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1409 provide the ``self`` argument.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1410
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1411
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1412 How can I organize my code to make it easier to change the base class?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1413 ----------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1414
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1415 You could define an alias for the base class, assign the real base class to it
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1416 before your class definition, and use the alias throughout your class. Then all
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1417 you have to change is the value assigned to the alias. Incidentally, this trick
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1418 is also handy if you want to decide dynamically (e.g. depending on availability
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1419 of resources) which base class to use. Example::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1420
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1421 BaseAlias = <real base class>
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1422
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1423 class Derived(BaseAlias):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1424 def meth(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1425 BaseAlias.meth(self)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1426 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1427
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1428
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1429 How do I create static class data and static class methods?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1430 -----------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1431
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1432 Both static data and static methods (in the sense of C++ or Java) are supported
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1433 in Python.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1434
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1435 For static data, simply define a class attribute. To assign a new value to the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1436 attribute, you have to explicitly use the class name in the assignment::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1437
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1438 class C:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1439 count = 0 # number of times C.__init__ called
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1440
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1441 def __init__(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1442 C.count = C.count + 1
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1443
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1444 def getcount(self):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1445 return C.count # or return self.count
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1446
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1447 ``c.count`` also refers to ``C.count`` for any ``c`` such that ``isinstance(c,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1448 C)`` holds, unless overridden by ``c`` itself or by some class on the base-class
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1449 search path from ``c.__class__`` back to ``C``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1450
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1451 Caution: within a method of C, an assignment like ``self.count = 42`` creates a
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1452 new and unrelated instance named "count" in ``self``'s own dict. Rebinding of a
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1453 class-static data name must always specify the class whether inside a method or
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1454 not::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1455
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1456 C.count = 314
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1457
73836
93f64ae51fff Remove outdate FAQ content
Antoine Pitrou <solipsis@pitrou.net>
parents: 73834
diff changeset
1458 Static methods are possible::
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1459
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1460 class C:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1461 @staticmethod
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1462 def static(arg1, arg2, arg3):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1463 # No 'self' parameter!
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1464 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1465
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1466 However, a far more straightforward way to get the effect of a static method is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1467 via a simple module-level function::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1468
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1469 def getcount():
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1470 return C.count
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1471
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1472 If your code is structured so as to define one class (or tightly related class
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1473 hierarchy) per module, this supplies the desired encapsulation.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1474
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1475
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1476 How can I overload constructors (or methods) in Python?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1477 -------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1478
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1479 This answer actually applies to all methods, but the question usually comes up
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1480 first in the context of constructors.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1481
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1482 In C++ you'd write
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1483
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1484 .. code-block:: c
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1485
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1486 class C {
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1487 C() { cout << "No arguments\n"; }
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1488 C(int i) { cout << "Argument is " << i << "\n"; }
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1489 }
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1490
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1491 In Python you have to write a single constructor that catches all cases using
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1492 default arguments. For example::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1493
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1494 class C:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1495 def __init__(self, i=None):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1496 if i is None:
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1497 print("No arguments")
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1498 else:
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1499 print("Argument is", i)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1500
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1501 This is not entirely equivalent, but close enough in practice.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1502
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1503 You could also try a variable-length argument list, e.g. ::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1504
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1505 def __init__(self, *args):
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1506 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1507
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1508 The same approach works for all method definitions.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1509
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1510
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1511 I try to use __spam and I get an error about _SomeClassName__spam.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1512 ------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1513
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1514 Variable names with double leading underscores are "mangled" to provide a simple
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1515 but effective way to define class private variables. Any identifier of the form
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1516 ``__spam`` (at least two leading underscores, at most one trailing underscore)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1517 is textually replaced with ``_classname__spam``, where ``classname`` is the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1518 current class name with any leading underscores stripped.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1519
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1520 This doesn't guarantee privacy: an outside user can still deliberately access
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1521 the "_classname__spam" attribute, and private values are visible in the object's
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1522 ``__dict__``. Many Python programmers never bother to use private variable
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1523 names at all.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1524
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1525
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1526 My class defines __del__ but it is not called when I delete the object.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1527 -----------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1528
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1529 There are several possible reasons for this.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1530
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1531 The del statement does not necessarily call :meth:`__del__` -- it simply
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1532 decrements the object's reference count, and if this reaches zero
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1533 :meth:`__del__` is called.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1534
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1535 If your data structures contain circular links (e.g. a tree where each child has
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1536 a parent reference and each parent has a list of children) the reference counts
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1537 will never go back to zero. Once in a while Python runs an algorithm to detect
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1538 such cycles, but the garbage collector might run some time after the last
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1539 reference to your data structure vanishes, so your :meth:`__del__` method may be
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1540 called at an inconvenient and random time. This is inconvenient if you're trying
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1541 to reproduce a problem. Worse, the order in which object's :meth:`__del__`
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1542 methods are executed is arbitrary. You can run :func:`gc.collect` to force a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1543 collection, but there *are* pathological cases where objects will never be
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1544 collected.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1545
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1546 Despite the cycle collector, it's still a good idea to define an explicit
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1547 ``close()`` method on objects to be called whenever you're done with them. The
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1548 ``close()`` method can then remove attributes that refer to subobjecs. Don't
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1549 call :meth:`__del__` directly -- :meth:`__del__` should call ``close()`` and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1550 ``close()`` should make sure that it can be called more than once for the same
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1551 object.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1552
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1553 Another way to avoid cyclical references is to use the :mod:`weakref` module,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1554 which allows you to point to objects without incrementing their reference count.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1555 Tree data structures, for instance, should use weak references for their parent
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1556 and sibling references (if they need them!).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1557
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1558 .. XXX relevant for Python 3?
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1559
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1560 If the object has ever been a local variable in a function that caught an
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1561 expression in an except clause, chances are that a reference to the object
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1562 still exists in that function's stack frame as contained in the stack trace.
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1563 Normally, calling :func:`sys.exc_clear` will take care of this by clearing
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1564 the last recorded exception.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1565
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1566 Finally, if your :meth:`__del__` method raises an exception, a warning message
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1567 is printed to :data:`sys.stderr`.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1568
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1569
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1570 How do I get a list of all instances of a given class?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1571 ------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1572
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1573 Python does not keep track of all instances of a class (or of a built-in type).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1574 You can program the class's constructor to keep track of all instances by
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1575 keeping a list of weak references to each instance.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1576
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1577
86230
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1578 Why does the result of ``id()`` appear to be not unique?
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1579 --------------------------------------------------------
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1580
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1581 The :func:`id` builtin returns an integer that is guaranteed to be unique during
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1582 the lifetime of the object. Since in CPython, this is the object's memory
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1583 address, it happens frequently that after an object is deleted from memory, the
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1584 next freshly created object is allocated at the same position in memory. This
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1585 is illustrated by this example:
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1586
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1587 >>> id(1000)
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1588 13901272
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1589 >>> id(2000)
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1590 13901272
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1591
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1592 The two ids belong to different integer objects that are created before, and
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1593 deleted immediately after execution of the ``id()`` call. To be sure that
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1594 objects whose id you want to examine are still alive, create another reference
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1595 to the object:
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1596
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1597 >>> a = 1000; b = 2000
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1598 >>> id(a)
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1599 13901272
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1600 >>> id(b)
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1601 13891296
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1602
0d5de993db66 Closes #13203: add a FAQ section about seemingly duplicate id()s.
Georg Brandl <georg@python.org>
parents: 84221
diff changeset
1603
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1604 Modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1605 =======
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1606
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1607 How do I create a .pyc file?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1608 ----------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1609
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1610 When a module is imported for the first time (or when the source is more recent
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1611 than the current compiled file) a ``.pyc`` file containing the compiled code
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1612 should be created in the same directory as the ``.py`` file.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1613
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1614 One reason that a ``.pyc`` file may not be created is permissions problems with
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1615 the directory. This can happen, for example, if you develop as one user but run
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1616 as another, such as if you are testing with a web server. Creation of a .pyc
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1617 file is automatic if you're importing a module and Python has the ability
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1618 (permissions, free space, etc...) to write the compiled module back to the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1619 directory.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1620
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1621 Running Python on a top level script is not considered an import and no
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1622 ``.pyc`` will be created. For example, if you have a top-level module
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1623 ``foo.py`` that imports another module ``xyz.py``, when you run ``foo``,
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1624 ``xyz.pyc`` will be created since ``xyz`` is imported, but no ``foo.pyc`` file
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1625 will be created since ``foo.py`` isn't being imported.
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1626
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1627 If you need to create ``foo.pyc`` -- that is, to create a ``.pyc`` file for a module
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1628 that is not imported -- you can, using the :mod:`py_compile` and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1629 :mod:`compileall` modules.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1630
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1631 The :mod:`py_compile` module can manually compile any module. One way is to use
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1632 the ``compile()`` function in that module interactively::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1633
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1634 >>> import py_compile
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1635 >>> py_compile.compile('foo.py') # doctest: +SKIP
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1636
84221
0113247f894b Tweak programming faq examples so that it (mostly) passes doctest.
R David Murray <rdmurray@bitdance.com>
parents: 84061
diff changeset
1637 This will write the ``.pyc`` to the same location as ``foo.py`` (or you can
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1638 override that with the optional parameter ``cfile``).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1639
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1640 You can also automatically compile all files in a directory or directories using
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1641 the :mod:`compileall` module. You can do it from the shell prompt by running
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1642 ``compileall.py`` and providing the path of a directory containing Python files
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1643 to compile::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1644
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1645 python -m compileall .
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1646
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1647
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1648 How do I find the current module name?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1649 --------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1650
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1651 A module can find out its own module name by looking at the predefined global
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1652 variable ``__name__``. If this has the value ``'__main__'``, the program is
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1653 running as a script. Many modules that are usually used by importing them also
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1654 provide a command-line interface or a self-test, and only execute this code
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1655 after checking ``__name__``::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1656
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1657 def main():
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1658 print('Running test...')
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1659 ...
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1660
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1661 if __name__ == '__main__':
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1662 main()
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1663
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1664
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1665 How can I have modules that mutually import each other?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1666 -------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1667
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1668 Suppose you have the following modules:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1669
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1670 foo.py::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1671
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1672 from bar import bar_var
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1673 foo_var = 1
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1674
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1675 bar.py::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1676
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1677 from foo import foo_var
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1678 bar_var = 2
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1679
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1680 The problem is that the interpreter will perform the following steps:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1681
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1682 * main imports foo
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1683 * Empty globals for foo are created
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1684 * foo is compiled and starts executing
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1685 * foo imports bar
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1686 * Empty globals for bar are created
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1687 * bar is compiled and starts executing
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1688 * bar imports foo (which is a no-op since there already is a module named foo)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1689 * bar.foo_var = foo.foo_var
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1690
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1691 The last step fails, because Python isn't done with interpreting ``foo`` yet and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1692 the global symbol dictionary for ``foo`` is still empty.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1693
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1694 The same thing happens when you use ``import foo``, and then try to access
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1695 ``foo.foo_var`` in global code.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1696
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1697 There are (at least) three possible workarounds for this problem.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1698
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1699 Guido van Rossum recommends avoiding all uses of ``from <module> import ...``,
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1700 and placing all code inside functions. Initializations of global variables and
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1701 class variables should use constants or built-in functions only. This means
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1702 everything from an imported module is referenced as ``<module>.<name>``.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1703
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1704 Jim Roskind suggests performing steps in the following order in each module:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1705
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1706 * exports (globals, functions, and classes that don't need imported base
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1707 classes)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1708 * ``import`` statements
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1709 * active code (including globals that are initialized from imported values).
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1710
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1711 van Rossum doesn't like this approach much because the imports appear in a
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1712 strange place, but it does work.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1713
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1714 Matthias Urlichs recommends restructuring your code so that the recursive import
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1715 is not necessary in the first place.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1716
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1717 These solutions are not mutually exclusive.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1718
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1719
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1720 __import__('x.y.z') returns <module 'x'>; how do I get z?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1721 ---------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1722
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1723 Try::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1724
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1725 __import__('x.y.z').y.z
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1726
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1727 For more realistic situations, you may have to do something like ::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1728
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1729 m = __import__(s)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1730 for i in s.split(".")[1:]:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1731 m = getattr(m, i)
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1732
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1733 See :mod:`importlib` for a convenience function called
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1734 :func:`~importlib.import_module`.
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1735
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1736
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1737
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1738 When I edit an imported module and reimport it, the changes don't show up. Why does this happen?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1739 -------------------------------------------------------------------------------------------------
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1740
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1741 For reasons of efficiency as well as consistency, Python only reads the module
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1742 file on the first time a module is imported. If it didn't, in a program
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1743 consisting of many modules where each one imports the same basic module, the
84138
3d3b9d456eb8 Issue #17177: Update the programming FAQ to use importlib
Brett Cannon <brett@python.org>
parents: 84061
diff changeset
1744 basic module would be parsed and re-parsed many times. To force re-reading of a
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1745 changed module, do this::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1746
84138
3d3b9d456eb8 Issue #17177: Update the programming FAQ to use importlib
Brett Cannon <brett@python.org>
parents: 84061
diff changeset
1747 import importlib
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1748 import modname
84138
3d3b9d456eb8 Issue #17177: Update the programming FAQ to use importlib
Brett Cannon <brett@python.org>
parents: 84061
diff changeset
1749 importlib.reload(modname)
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1750
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1751 Warning: this technique is not 100% fool-proof. In particular, modules
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1752 containing statements like ::
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1753
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1754 from modname import some_objects
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1755
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1756 will continue to work with the old version of the imported objects. If the
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1757 module contains class definitions, existing class instances will *not* be
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1758 updated to use the new class definition. This can result in the following
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1759 paradoxical behaviour:
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1760
84138
3d3b9d456eb8 Issue #17177: Update the programming FAQ to use importlib
Brett Cannon <brett@python.org>
parents: 84061
diff changeset
1761 >>> import importlib
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1762 >>> import cls
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1763 >>> c = cls.C() # Create an instance of C
84138
3d3b9d456eb8 Issue #17177: Update the programming FAQ to use importlib
Brett Cannon <brett@python.org>
parents: 84061
diff changeset
1764 >>> importlib.reload(cls)
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1765 <module 'cls' from 'cls.py'>
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1766 >>> isinstance(c, cls.C) # isinstance is false?!?
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1767 False
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1768
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1769 The nature of the problem is made clear if you print out the "identity" of the
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1770 class objects:
56890
cef5cb270fdf Merged revisions 75374 via svnmerge from
Georg Brandl <georg@python.org>
parents:
diff changeset
1771
61797
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1772 >>> hex(id(c.__class__))
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1773 '0x7352a0'
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1774 >>> hex(id(cls.C))
6ca2e6b3bf31 Merged revisions 76888,76922,81406 via svnmerge from
Georg Brandl <georg@python.org>
parents: 57244
diff changeset
1775 '0x4198d0'