Mercurial > cpython-lru_cache-weakref
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 |
| 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 | 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 | 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' |
