mirror of https://github.com/python/cpython
Merged revisions 65487 (with heavy modifications for Py3k as well as some cleanups of the type heirarchy) via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r65487 | nick.coghlan | 2008-08-04 22:40:59 +1000 (Mon, 04 Aug 2008) | 1 line Issue 643841: better documentation of the special method lookup process, especially for new-style classes. Also removes the warnings about not being authoritative for new-style classes - the language reference actually covers those fairly well now (albeit in a fashion that isn't always particularly easy to follow). ........
This commit is contained in:
parent
0d855393e6
commit
3a5d7e34ad
|
@ -36,7 +36,7 @@ Every object has an identity, a type and a value. An object's *identity* never
|
||||||
changes once it has been created; you may think of it as the object's address in
|
changes once it has been created; you may think of it as the object's address in
|
||||||
memory. The ':keyword:`is`' operator compares the identity of two objects; the
|
memory. The ':keyword:`is`' operator compares the identity of two objects; the
|
||||||
:func:`id` function returns an integer representing its identity (currently
|
:func:`id` function returns an integer representing its identity (currently
|
||||||
implemented as its address). An object's :dfn:`type` is also unchangeable.
|
implemented as its address). An object's :dfn:`type` is also unchangeable. [#]_
|
||||||
An object's type determines the operations that the object supports (e.g., "does
|
An object's type determines the operations that the object supports (e.g., "does
|
||||||
it have a length?") and also defines the possible values for objects of that
|
it have a length?") and also defines the possible values for objects of that
|
||||||
type. The :func:`type` function returns an object's type (which is an object
|
type. The :func:`type` function returns an object's type (which is an object
|
||||||
|
@ -77,7 +77,7 @@ garbage-collected, but since garbage collection is not guaranteed to happen,
|
||||||
such objects also provide an explicit way to release the external resource,
|
such objects also provide an explicit way to release the external resource,
|
||||||
usually a :meth:`close` method. Programs are strongly recommended to explicitly
|
usually a :meth:`close` method. Programs are strongly recommended to explicitly
|
||||||
close such objects. The ':keyword:`try`...\ :keyword:`finally`' statement
|
close such objects. The ':keyword:`try`...\ :keyword:`finally`' statement
|
||||||
provides a convenient way to do this.
|
and the ':keyword:`with`' statement provide convenient ways to do this.
|
||||||
|
|
||||||
.. index:: single: container
|
.. index:: single: container
|
||||||
|
|
||||||
|
@ -116,7 +116,8 @@ The standard type hierarchy
|
||||||
Below is a list of the types that are built into Python. Extension modules
|
Below is a list of the types that are built into Python. Extension modules
|
||||||
(written in C, Java, or other languages, depending on the implementation) can
|
(written in C, Java, or other languages, depending on the implementation) can
|
||||||
define additional types. Future versions of Python may add types to the type
|
define additional types. Future versions of Python may add types to the type
|
||||||
hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.).
|
hierarchy (e.g., rational numbers, efficiently stored arrays of integers, etc.),
|
||||||
|
although such additions will often be provided via the standard library instead.
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: attribute
|
single: attribute
|
||||||
|
@ -172,7 +173,7 @@ Ellipsis
|
||||||
|
|
||||||
There are two types of integers:
|
There are two types of integers:
|
||||||
|
|
||||||
Integers
|
Integers (:class:`int`)
|
||||||
|
|
||||||
These represent numbers in an unlimited range, subject to available (virtual)
|
These represent numbers in an unlimited range, subject to available (virtual)
|
||||||
memory only. For the purpose of shift and mask operations, a binary
|
memory only. For the purpose of shift and mask operations, a binary
|
||||||
|
@ -180,7 +181,7 @@ Ellipsis
|
||||||
2's complement which gives the illusion of an infinite string of sign bits
|
2's complement which gives the illusion of an infinite string of sign bits
|
||||||
extending to the left.
|
extending to the left.
|
||||||
|
|
||||||
Booleans
|
Booleans (:class:`bool`)
|
||||||
.. index::
|
.. index::
|
||||||
object: Boolean
|
object: Boolean
|
||||||
single: False
|
single: False
|
||||||
|
@ -212,7 +213,7 @@ Ellipsis
|
||||||
overhead of using objects in Python, so there is no reason to complicate the
|
overhead of using objects in Python, so there is no reason to complicate the
|
||||||
language with two kinds of floating point numbers.
|
language with two kinds of floating point numbers.
|
||||||
|
|
||||||
:class:`numbers.Complex`
|
:class:`numbers.Complex` (:class:`complex`)
|
||||||
.. index::
|
.. index::
|
||||||
object: complex
|
object: complex
|
||||||
pair: complex; number
|
pair: complex; number
|
||||||
|
@ -293,6 +294,15 @@ Sequences
|
||||||
parentheses must be usable for grouping of expressions). An empty
|
parentheses must be usable for grouping of expressions). An empty
|
||||||
tuple can be formed by an empty pair of parentheses.
|
tuple can be formed by an empty pair of parentheses.
|
||||||
|
|
||||||
|
Bytes
|
||||||
|
.. index:: bytes, byte
|
||||||
|
|
||||||
|
A bytes object is an immutable array. The items are 8-bit bytes,
|
||||||
|
represented by integers in the range 0 <= x < 256. Bytes literals
|
||||||
|
(like ``b'abc'`` and the built-in function :func:`bytes` can be used to
|
||||||
|
construct bytes objects. Also, bytes objects can be decoded to strings
|
||||||
|
via the :meth:`decode` method.
|
||||||
|
|
||||||
Mutable sequences
|
Mutable sequences
|
||||||
.. index::
|
.. index::
|
||||||
object: mutable sequence
|
object: mutable sequence
|
||||||
|
@ -316,19 +326,18 @@ Sequences
|
||||||
placing a comma-separated list of expressions in square brackets. (Note
|
placing a comma-separated list of expressions in square brackets. (Note
|
||||||
that there are no special cases needed to form lists of length 0 or 1.)
|
that there are no special cases needed to form lists of length 0 or 1.)
|
||||||
|
|
||||||
Bytes
|
Byte Arrays
|
||||||
.. index:: bytes, byte
|
.. index:: bytearray
|
||||||
|
|
||||||
A bytes object is a mutable array. The items are 8-bit bytes,
|
A bytearray object is a mutable array. They are created by the built-in
|
||||||
represented by integers in the range 0 <= x < 256. Bytes literals
|
:func:`bytearray` constructor. Aside from being mutable (and hence
|
||||||
(like ``b'abc'`` and the built-in function :func:`bytes` can be used to
|
unhashable), byte arrays otherwise provide the same interface and
|
||||||
construct bytes objects. Also, bytes objects can be decoded to strings
|
functionality as immutable bytes objects.
|
||||||
via the :meth:`decode` method.
|
|
||||||
|
|
||||||
.. index:: module: array
|
.. index:: module: array
|
||||||
|
|
||||||
The extension module :mod:`array` provides an additional example of a
|
The extension module :mod:`array` provides an additional example of a
|
||||||
mutable sequence type.
|
mutable sequence type, as does the :mod:`collections` module.
|
||||||
|
|
||||||
Set types
|
Set types
|
||||||
.. index::
|
.. index::
|
||||||
|
@ -399,7 +408,8 @@ Mappings
|
||||||
module: bsddb
|
module: bsddb
|
||||||
|
|
||||||
The extension modules :mod:`dbm.ndbm`, :mod:`dbm.gnu`, and :mod:`bsddb`
|
The extension modules :mod:`dbm.ndbm`, :mod:`dbm.gnu`, and :mod:`bsddb`
|
||||||
provide additional examples of mapping types.
|
provide additional examples of mapping types, as does the :mod:`collections`
|
||||||
|
module.
|
||||||
|
|
||||||
Callable types
|
Callable types
|
||||||
.. index::
|
.. index::
|
||||||
|
@ -524,7 +534,7 @@ Callable types
|
||||||
User-defined method objects may be created when getting an attribute of a
|
User-defined method objects may be created when getting an attribute of a
|
||||||
class (perhaps via an instance of that class), if that attribute is a
|
class (perhaps via an instance of that class), if that attribute is a
|
||||||
user-defined function object or a class method object.
|
user-defined function object or a class method object.
|
||||||
|
|
||||||
When an instance method object is created by retrieving a user-defined
|
When an instance method object is created by retrieving a user-defined
|
||||||
function object from a class via one of its instances, its
|
function object from a class via one of its instances, its
|
||||||
:attr:`__self__` attribute is the instance, and the method object is said
|
:attr:`__self__` attribute is the instance, and the method object is said
|
||||||
|
@ -571,11 +581,11 @@ Callable types
|
||||||
single: generator; iterator
|
single: generator; iterator
|
||||||
|
|
||||||
A function or method which uses the :keyword:`yield` statement (see section
|
A function or method which uses the :keyword:`yield` statement (see section
|
||||||
:ref:`yield`) is called a :dfn:`generator
|
:ref:`yield`) is called a :dfn:`generator function`. Such a function, when
|
||||||
function`. Such a function, when called, always returns an iterator object
|
called, always returns an iterator object which can be used to execute the
|
||||||
which can be used to execute the body of the function: calling the iterator's
|
body of the function: calling the iterator's :meth:`__next__` method will
|
||||||
:meth:`__next__` method will cause the function to execute until it provides a
|
cause the function to execute until it provides a value using the
|
||||||
value using the :keyword:`yield` statement. When the function executes a
|
:keyword:`yield` statement. When the function executes a
|
||||||
:keyword:`return` statement or falls off the end, a :exc:`StopIteration`
|
:keyword:`return` statement or falls off the end, a :exc:`StopIteration`
|
||||||
exception is raised and the iterator will have reached the end of the set of
|
exception is raised and the iterator will have reached the end of the set of
|
||||||
values to be returned.
|
values to be returned.
|
||||||
|
@ -655,18 +665,21 @@ Modules
|
||||||
extension modules loaded dynamically from a shared library, it is the pathname
|
extension modules loaded dynamically from a shared library, it is the pathname
|
||||||
of the shared library file.
|
of the shared library file.
|
||||||
|
|
||||||
.. XXX "Classes" and "Instances" is outdated!
|
|
||||||
see http://www.python.org/doc/newstyle.html for newstyle information
|
|
||||||
|
|
||||||
Custom classes
|
Custom classes
|
||||||
Class objects are created by class definitions (see section :ref:`class`). A
|
Custon class types are typically created by class definitions (see section
|
||||||
class has a namespace implemented by a dictionary object. Class attribute
|
:ref:`class`). A class has a namespace implemented by a dictionary object.
|
||||||
references are translated to lookups in this dictionary, e.g., ``C.x`` is
|
Class attribute references are translated to lookups in this dictionary, e.g.,
|
||||||
translated to ``C.__dict__["x"]``. When the attribute name is not found
|
``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of
|
||||||
there, the attribute search continues in the base classes. The search is
|
hooks which allow for other means of locating attributes). When the attribute
|
||||||
depth-first, left-to-right in the order of occurrence in the base class list.
|
name is not found there, the attribute search continues in the base classes.
|
||||||
|
This search of the base classes uses the C3 method resolution order which
|
||||||
|
behaves correctly even in the presence of 'diamond' inheritance structures
|
||||||
|
where there are multiple inheritance paths leading back to a common ancestor.
|
||||||
|
Additional details on the C3 MRO used by Python can be found in the
|
||||||
|
documentation accompanying the 2.3 release at
|
||||||
|
http://www.python.org/download/releases/2.3/mro/.
|
||||||
|
|
||||||
.. XXX document descriptors and new MRO
|
.. XXX: Could we add that MRO doc as an appendix to the language ref?
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
object: class
|
object: class
|
||||||
|
@ -980,25 +993,10 @@ A class can implement certain operations that are invoked by special syntax
|
||||||
with special names. This is Python's approach to :dfn:`operator overloading`,
|
with special names. This is Python's approach to :dfn:`operator overloading`,
|
||||||
allowing classes to define their own behavior with respect to language
|
allowing classes to define their own behavior with respect to language
|
||||||
operators. For instance, if a class defines a method named :meth:`__getitem__`,
|
operators. For instance, if a class defines a method named :meth:`__getitem__`,
|
||||||
and ``x`` is an instance of this class, then ``x[i]`` is equivalent to
|
and ``x`` is an instance of this class, then ``x[i]`` is roughly equivalent
|
||||||
``x.__getitem__(i)``. Except where mentioned, attempts to execute an operation
|
to ``type(x).__getitem__(x, i)``. Except where mentioned, attempts to execute an
|
||||||
raise an exception when no appropriate method is defined.
|
operation raise an exception when no appropriate method is defined (typically
|
||||||
|
:exc:`AttributeError` or :exc:`TypeError`).
|
||||||
.. XXX above translation is not correct for new-style classes!
|
|
||||||
|
|
||||||
Special methods are only guaranteed to work if defined in an object's class, not
|
|
||||||
in the object's instance dictionary. That explains why this won't work::
|
|
||||||
|
|
||||||
>>> class C:
|
|
||||||
... pass
|
|
||||||
...
|
|
||||||
>>> c = C()
|
|
||||||
>>> c.__len__ = lambda: 5
|
|
||||||
>>> len(c)
|
|
||||||
Traceback (most recent call last):
|
|
||||||
File "<stdin>", line 1, in <module>
|
|
||||||
TypeError: object of type 'C' has no len()
|
|
||||||
|
|
||||||
|
|
||||||
When implementing a class that emulates any built-in type, it is important that
|
When implementing a class that emulates any built-in type, it is important that
|
||||||
the emulation only be implemented to the degree that it makes sense for the
|
the emulation only be implemented to the degree that it makes sense for the
|
||||||
|
@ -1277,7 +1275,7 @@ access (use of, assignment to, or deletion of ``x.name``) for class instances.
|
||||||
Note that if the attribute is found through the normal mechanism,
|
Note that if the attribute is found through the normal mechanism,
|
||||||
:meth:`__getattr__` is not called. (This is an intentional asymmetry between
|
:meth:`__getattr__` is not called. (This is an intentional asymmetry between
|
||||||
:meth:`__getattr__` and :meth:`__setattr__`.) This is done both for efficiency
|
:meth:`__getattr__` and :meth:`__setattr__`.) This is done both for efficiency
|
||||||
reasons and because otherwise :meth:`__setattr__` would have no way to access
|
reasons and because otherwise :meth:`__getattr__` would have no way to access
|
||||||
other attributes of the instance. Note that at least for instance variables,
|
other attributes of the instance. Note that at least for instance variables,
|
||||||
you can fake total control by not inserting any values in the instance attribute
|
you can fake total control by not inserting any values in the instance attribute
|
||||||
dictionary (but instead inserting them in another object). See the
|
dictionary (but instead inserting them in another object). See the
|
||||||
|
@ -1296,6 +1294,12 @@ access (use of, assignment to, or deletion of ``x.name``) for class instances.
|
||||||
method with the same name to access any attributes it needs, for example,
|
method with the same name to access any attributes it needs, for example,
|
||||||
``object.__getattribute__(self, name)``.
|
``object.__getattribute__(self, name)``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This method may still be bypassed when looking up special methods as the
|
||||||
|
result of implicit invocation via language syntax or builtin functions.
|
||||||
|
See :ref:`special-lookup`.
|
||||||
|
|
||||||
|
|
||||||
.. method:: object.__setattr__(self, name, value)
|
.. method:: object.__setattr__(self, name, value)
|
||||||
|
|
||||||
|
@ -1881,8 +1885,89 @@ For more information on context managers, see :ref:`typecontextmanager`.
|
||||||
The specification, background, and examples for the Python :keyword:`with`
|
The specification, background, and examples for the Python :keyword:`with`
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
|
|
||||||
|
.. _special-lookup:
|
||||||
|
|
||||||
|
Special method lookup
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
For custom classes, implicit invocations of special methods are only guaranteed
|
||||||
|
to work correctly if defined on an object's type, not in the object's instance
|
||||||
|
dictionary. That behaviour is the reason why the following code raises an
|
||||||
|
exception::
|
||||||
|
|
||||||
|
>>> class C(object):
|
||||||
|
... pass
|
||||||
|
...
|
||||||
|
>>> c = C()
|
||||||
|
>>> c.__len__ = lambda: 5
|
||||||
|
>>> len(c)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
TypeError: object of type 'C' has no len()
|
||||||
|
|
||||||
|
The rationale behind this behaviour lies with a number of special methods such
|
||||||
|
as :meth:`__hash__` and :meth:`__repr__` that are implemented by all objects,
|
||||||
|
including type objects. If the implicit lookup of these methods used the
|
||||||
|
conventional lookup process, they would fail when invoked on the type object
|
||||||
|
itself::
|
||||||
|
|
||||||
|
>>> 1 .__hash__() == hash(1)
|
||||||
|
True
|
||||||
|
>>> int.__hash__() == hash(int)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
TypeError: descriptor '__hash__' of 'int' object needs an argument
|
||||||
|
|
||||||
|
Incorrectly attempting to invoke an unbound method of a class in this way is
|
||||||
|
sometimes referred to as 'metaclass confusion', and is avoided by bypassing
|
||||||
|
the instance when looking up special methods::
|
||||||
|
|
||||||
|
>>> type(1).__hash__(1) == hash(1)
|
||||||
|
True
|
||||||
|
>>> type(int).__hash__(int) == hash(int)
|
||||||
|
True
|
||||||
|
|
||||||
|
In addition to bypassing any instance attributes in the interest of
|
||||||
|
correctness, implicit special method lookup may also bypass the
|
||||||
|
:meth:`__getattribute__` method even of the object's metaclass::
|
||||||
|
|
||||||
|
>>> class Meta(type):
|
||||||
|
... def __getattribute__(*args):
|
||||||
|
... print "Metaclass getattribute invoked"
|
||||||
|
... return type.__getattribute__(*args)
|
||||||
|
...
|
||||||
|
>>> class C(object):
|
||||||
|
... __metaclass__ = Meta
|
||||||
|
... def __len__(self):
|
||||||
|
... return 10
|
||||||
|
... def __getattribute__(*args):
|
||||||
|
... print "Class getattribute invoked"
|
||||||
|
... return object.__getattribute__(*args)
|
||||||
|
...
|
||||||
|
>>> c = C()
|
||||||
|
>>> c.__len__() # Explicit lookup via instance
|
||||||
|
Class getattribute invoked
|
||||||
|
10
|
||||||
|
>>> type(c).__len__(c) # Explicit lookup via type
|
||||||
|
Metaclass getattribute invoked
|
||||||
|
10
|
||||||
|
>>> len(c) # Implicit lookup
|
||||||
|
10
|
||||||
|
|
||||||
|
Bypassing the :meth:`__getattribute__` machinery in this fashion
|
||||||
|
provides significant scope for speed optimisations within the
|
||||||
|
interpreter, at the cost of some flexibility in the handling of
|
||||||
|
special methods (the special method *must* be set on the class
|
||||||
|
object itself in order to be consistently invoked by the interpreter).
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
|
.. [#] It *is* possible in some cases to change an object's type, under certain
|
||||||
|
controlled conditions. It generally isn't a good idea though, since it can
|
||||||
|
lead to some very strange behaviour if it is handled incorrectly.
|
||||||
|
|
||||||
.. [#] A descriptor can define any combination of :meth:`__get__`,
|
.. [#] A descriptor can define any combination of :meth:`__get__`,
|
||||||
:meth:`__set__` and :meth:`__delete__`. If it does not define :meth:`__get__`,
|
:meth:`__set__` and :meth:`__delete__`. If it does not define :meth:`__get__`,
|
||||||
then accessing the attribute even on an instance will return the descriptor
|
then accessing the attribute even on an instance will return the descriptor
|
||||||
|
|
Loading…
Reference in New Issue