diff options
Diffstat (limited to 'Doc/reference/datamodel.rst')
-rw-r--r-- | Doc/reference/datamodel.rst | 122 |
1 files changed, 100 insertions, 22 deletions
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 6894c7c..246e2e3 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -686,33 +686,36 @@ Modules Attribute assignment updates the module's namespace dictionary, e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. - .. index:: single: __dict__ (module attribute) - - Special read-only attribute: :attr:`~object.__dict__` is the module's namespace as a - dictionary object. - - .. impl-detail:: - - Because of the way CPython clears module dictionaries, the module - dictionary will be cleared when the module falls out of scope even if the - dictionary still has live references. To avoid this, copy the dictionary - or keep the module around while using its dictionary directly. - .. index:: single: __name__ (module attribute) single: __doc__ (module attribute) single: __file__ (module attribute) + single: __annotations__ (module attribute) pair: module; namespace Predefined (writable) attributes: :attr:`__name__` is the module's name; :attr:`__doc__` is the module's documentation string, or ``None`` if - unavailable; :attr:`__file__` is the pathname of the file from which the + unavailable; :attr:`__annotations__` (optional) is a dictionary containing + :term:`variable annotations <variable annotation>` collected during module + body execution; :attr:`__file__` is the pathname of the file from which the module was loaded, if it was loaded from a file. The :attr:`__file__` attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file. + .. index:: single: __dict__ (module attribute) + + Special read-only attribute: :attr:`~object.__dict__` is the module's + namespace as a dictionary object. + + .. impl-detail:: + + Because of the way CPython clears module dictionaries, the module + dictionary will be cleared when the module falls out of scope even if the + dictionary still has live references. To avoid this, copy the dictionary + or keep the module around while using its dictionary directly. + Custom classes Custom class types are typically created by class definitions (see section :ref:`class`). A class has a namespace implemented by a dictionary object. @@ -761,13 +764,17 @@ Custom classes single: __dict__ (class attribute) single: __bases__ (class attribute) single: __doc__ (class attribute) + single: __annotations__ (class attribute) Special attributes: :attr:`~definition.__name__` is the class name; :attr:`__module__` is the module name in which the class was defined; :attr:`~object.__dict__` is the dictionary containing the class's namespace; :attr:`~class.__bases__` is a tuple (possibly empty or a singleton) containing the base classes, in the order of their occurrence in the base class list; :attr:`__doc__` is the - class's documentation string, or None if undefined. + class's documentation string, or None if undefined; + :attr:`__annotations__` (optional) is a dictionary containing + :term:`variable annotations <variable annotation>` collected during + class body execution. Class instances .. index:: @@ -1063,6 +1070,12 @@ to ``type(x).__getitem__(x, i)``. Except where mentioned, attempts to execute a operation raise an exception when no appropriate method is defined (typically :exc:`AttributeError` or :exc:`TypeError`). +Setting a special method to ``None`` indicates that the corresponding +operation is not available. For example, if a class sets +:meth:`__iter__` to ``None``, the class is not iterable, so calling +:func:`iter` on its instances will raise a :exc:`TypeError` (without +falling back to :meth:`__getitem__`). [#]_ + 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 object being modelled. For example, some sequences may work well with retrieval @@ -1233,8 +1246,9 @@ Basic customization .. method:: object.__format__(self, format_spec) - Called by the :func:`format` built-in function (and by extension, the - :meth:`str.format` method of class :class:`str`) to produce a "formatted" + Called by the :func:`format` built-in function, + and by extension, evaluation of :ref:`formatted string literals + <f-strings>` and the :meth:`str.format` method, to produce a "formatted" string representation of an object. The ``format_spec`` argument is a string that contains a description of the formatting options desired. The interpretation of the ``format_spec`` argument is up to the type @@ -1491,6 +1505,14 @@ class' :attr:`~object.__dict__`. Called to delete the attribute on an instance *instance* of the owner class. +.. method:: object.__set_name__(self, owner, name) + + Called at the time the owning class *owner* is created. The + descriptor has been assigned to *name*. + + .. versionadded:: 3.6 + + The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module as specifying the class where this object was defined (setting this appropriately can assist in runtime introspection of dynamic class attributes). @@ -1628,11 +1650,56 @@ Notes on using *__slots__* * *__class__* assignment works only if both classes have the same *__slots__*. -.. _metaclasses: +.. _class-customization: Customizing class creation -------------------------- +Whenever a class inherits from another class, *__init_subclass__* is +called on that class. This way, it is possible to write classes which +change the behavior of subclasses. This is closely related to class +decorators, but where class decorators only affect the specific class they're +applied to, ``__init_subclass__`` solely applies to future subclasses of the +class defining the method. + +.. classmethod:: object.__init_subclass__(cls) + + This method is called whenever the containing class is subclassed. + *cls* is then the new subclass. If defined as a normal instance method, + this method is implicitly converted to a class method. + + Keyword arguments which are given to a new class are passed to + the parent's class ``__init_subclass__``. For compatibility with + other classes using ``__init_subclass__``, one should take out the + needed keyword arguments and pass the others over to the base + class, as in:: + + class Philosopher: + def __init_subclass__(cls, default_name, **kwargs): + super().__init_subclass__(**kwargs) + cls.default_name = default_name + + class AustralianPhilosopher(Philosopher, default_name="Bruce"): + pass + + The default implementation ``object.__init_subclass__`` does + nothing, but raises an error if it is called with any arguments. + + .. note:: + + The metaclass hint ``metaclass`` is consumed by the rest of the type + machinery, and is never passed to ``__init_subclass__`` implementations. + The actual metaclass (rather than the explicit hint) can be accessed as + ``type(cls)``. + + .. versionadded:: 3.6 + + +.. _metaclasses: + +Metaclasses +^^^^^^^^^^^ + By default, classes are constructed using :func:`type`. The class body is executed in a new namespace and the class name is bound locally to the result of ``type(name, bases, namespace)``. @@ -1690,7 +1757,7 @@ as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). If the metaclass has no ``__prepare__`` attribute, then the class namespace -is initialised as an empty :func:`dict` instance. +is initialised as an empty ordered mapping. .. seealso:: @@ -1734,9 +1801,9 @@ included in the class definition (if any) and the resulting object is bound in the local namespace as the defined class. When a new class is created by ``type.__new__``, the object provided as the -namespace parameter is copied to a standard Python dictionary and the original -object is discarded. The new copy becomes the :attr:`~object.__dict__` attribute -of the class object. +namespace parameter is copied to a new ordered mapping and the original +object is discarded. The new copy is wrapped in a read-only proxy, which +becomes the :attr:`~object.__dict__` attribute of the class object. .. seealso:: @@ -2059,7 +2126,7 @@ left undefined. (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected (swapped) operands. These functions are only called if the left operand does - not support the corresponding operation and the operands are of different + not support the corresponding operation [#]_ and the operands are of different types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns *NotImplemented*. @@ -2475,6 +2542,17 @@ An example of an asynchronous context manager class:: controlled conditions. It generally isn't a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly. +.. [#] The :meth:`__hash__`, :meth:`__iter__`, :meth:`__reversed__`, and + :meth:`__contains__` methods have special handling for this; others + will still raise a :exc:`TypeError`, but may do so by relying on + the behavior that ``None`` is not callable. + +.. [#] "Does not support" here means that the class has no such method, or + the method returns ``NotImplemented``. Do not set the method to + ``None`` if you want to force fallback to the right operand's reflected + method--that will instead have the opposite effect of explicitly + *blocking* such fallback. + .. [#] For operands of the same type, it is assumed that if the non-reflected method (such as :meth:`__add__`) fails the operation is not supported, which is why the reflected method is not called. |