diff --git a/Doc/glossary.rst b/Doc/glossary.rst index a31bd53f06294d..62570d53dfb45c 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -819,6 +819,13 @@ Glossary See also :term:`subscript`. + instance dictionary + A :term:`dictionary` that stores an object's :term:`attributes `. + Exposed as :attr:`~object.__dict__`. + Note that some attributes may be stored elsewhere, such as in + :attr:`~object.__slots__`, on the object's type, or through + :term:`descriptors `. + interactive Python has an interactive interpreter which means you can enter statements and expressions at the interpreter prompt, immediately diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 558f94e65f6c3f..5639594e459c50 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1285,13 +1285,25 @@ Primaries .. index:: single: primary -Primaries represent the most tightly bound operations of the language. Their -syntax is: +Primaries represent the most tightly bound operations of the language. +They are: + +- bare :ref:`atoms `, +- :ref:`attribute references `, such as ``math.pi``, +- :ref:`subscriptions and slicings `, such as ``names[0]``, and +- :ref:`calls `, such as ``print()``. + +The formal syntax of primaries is: + +.. grammar-snippet:: + :group: python-grammar -.. productionlist:: python-grammar primary: `atom` | `attributeref` | `subscription` | `call` +.. index:: + pair: exception; AttributeError + .. _attribute-references: Attribute references @@ -1301,30 +1313,76 @@ Attribute references pair: attribute; reference single: . (dot); attribute reference -An attribute reference is a primary followed by a period and a name: +An :dfn:`attribute reference` asks an object for an :term:`attribute` -- +a named value associated with that object. +Syntactically, an attribute reference is a :ref:`primary ` +expression followed by a dot (``.``) and an :ref:`identifier ` +that names the attribute. +For example:: -.. productionlist:: python-grammar - attributeref: `primary` "." `identifier` + >>> import math -.. index:: - pair: exception; AttributeError - pair: object; module - pair: object; list + >>> math.pi # get the `pi` attribute of the `math` module + 3.141592653589793 + + >>> (3 + 2j).real # get the `real` part of a complex number + 3.0 + +At runtime, the primary expression is evaluated, and the result's +:meth:`~object.__getattribute__` :term:`special method` is called to to produce +the attribute of the given name. +By default, :meth:`!__getattribute__` looks attributes up +in several places, such as the object's :term:`instance dictionary`, +its type's attributes and descriptors, and the type's +:meth:`~object.__getattr__` method, if any. +Typically, :meth:`!__getattribute__` raises :exc:`AttributeError` if +the attribute is not found, and it returns the same object each time +it's called with a given object and name. +However, the method is called each time an attribute access is evaluated, +and it can raise different errors or return a differerent object each time. -The primary must evaluate to an object of a type that supports attribute -references, which most objects do. This object is then asked to produce the -attribute whose name is the identifier. The type and value produced is -determined by the object. Multiple evaluations of the same attribute -reference may yield different objects. +.. note:: + + When customizing the behavior of attribute references on a class you define, + consider adding a descriptor (for example, using :class:`property`) + or overriding :meth:`~object.__getattr__`, rather than replacing the entire + attribute lookup mechanism by overriding :meth:`!__getattribute__` itself. + See :ref:`attribute-access` for details. + +Attribute references may also be used as targets in +:ref:`assignment ` or :ref:`deletion ` statements. +In these cases, the interpreter will call an object's +:meth:`~object.__setattr__` or :meth:`~object.__delattr__` +:term:`special method`, respectively, +instead of :meth:`~object.__getattribute__`. + +.. code-block:: + + >>> from types import SimpleNamespace + >>> obj = SimpleNamespace() -This production can be customized by overriding the -:meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` -method. The :meth:`!__getattribute__` method is called first and either -returns a value or raises :exc:`AttributeError` if the attribute is not -available. + >>> obj.color = 'green' # set the `color` attribute on `obj` + >>> obj.color + 'green' + >>> obj + namespace(color='green') -If an :exc:`AttributeError` is raised and the object has a :meth:`!__getattr__` -method, that method is called as a fallback. + >>> del obj.color # delete the `color` attribute on `obj` + >>> obj + namespace() + + >>> del obj.color # delete an attribute that doesn't exist any more + Traceback (most recent call last): + ... + AttributeError: 'types.SimpleNamespace' object has no attribute 'color' + + +The formal grammar of attribute references is: + +.. grammar-snippet:: + :group: python-grammar + + attributeref: `primary` "." `identifier` .. _subscriptions: