Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,13 @@ Glossary

See also :term:`subscript`.

instance dictionary
A :term:`dictionary` that stores an object's :term:`attributes <attribute>`.
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 <descriptor>`.

interactive
Python has an interactive interpreter which means you can enter
statements and expressions at the interpreter prompt, immediately
Expand Down
102 changes: 80 additions & 22 deletions Doc/reference/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <atoms>`,
- :ref:`attribute references <attribute-references>`, such as ``math.pi``,
- :ref:`subscriptions and slicings <subscriptions>`, such as ``names[0]``, and
- :ref:`calls <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
Expand All @@ -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 <primaries>`
expression followed by a dot (``.``) and an :ref:`identifier <identifiers>`
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 <assignment>` or :ref:`deletion <del>` 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:

Expand Down
Loading