#5621: refactor description of how class/instance attributes interact on a.x=a.x+1 or augassign.

This commit is contained in:
Georg Brandl 2009-09-16 10:12:06 +00:00
parent 83130c3942
commit f4e6b98b01
1 changed files with 24 additions and 13 deletions

View File

@ -151,11 +151,30 @@ Assignment of an object to a single target is recursively defined as follows.
* If the target is an attribute reference: The primary expression in the
reference is evaluated. It should yield an object with assignable attributes;
if this is not the case, :exc:`TypeError` is raised. That object is then asked
to assign the assigned object to the given attribute; if it cannot perform the
assignment, it raises an exception (usually but not necessarily
if this is not the case, :exc:`TypeError` is raised. That object is then
asked to assign the assigned object to the given attribute; if it cannot
perform the assignment, it raises an exception (usually but not necessarily
:exc:`AttributeError`).
.. _attr-target-note:
Note: If the object is a class instance and the attribute reference occurs on
both sides of the assignment operator, the RHS expression, ``a.x`` can access
either an instance attribute or (if no instance attribute exists) a class
attribute. The LHS target ``a.x`` is always set as an instance attribute,
creating it if necessary. Thus, the two occurrences of ``a.x`` do not
necessarily refer to the same attribute: if the RHS expression refers to a
class attribute, the LHS creates a new instance attribute as the target of the
assignment::
class Cls:
x = 3 # class variable
inst = Cls()
inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3
This description does not necessarily apply to descriptor attributes, such as
properties created with :func:`property`.
.. index::
pair: subscription; assignment
object: mutable
@ -253,16 +272,8 @@ same way as normal assignments. Similarly, with the exception of the possible
*in-place* behavior, the binary operation performed by augmented assignment is
the same as the normal binary operations.
For targets which are attribute references, the initial value is retrieved with
a :meth:`getattr` and the result is assigned with a :meth:`setattr`. Notice
that the two methods do not necessarily refer to the same variable. When
:meth:`getattr` refers to a class variable, :meth:`setattr` still writes to an
instance variable. For example::
class A:
x = 3 # class variable
a = A()
a.x += 1 # writes a.x as 4 leaving A.x as 3
For targets which are attribute references, the same :ref:`caveat about class
and instance attributes <attr-target-note>` applies as for regular assignments.
.. _assert: