Class Variable Access and Assignment

Bengt Richter bokr at oz.net
Sun Nov 6 16:19:15 EST 2005


On Sun, 06 Nov 2005 12:23:02 -0500, Christopher Subich <spam.csubich+spam+block at subich.nospam.com> wrote:

>Bengt Richter wrote:
>> On Fri, 04 Nov 2005 10:28:52 -0500, Christopher Subich <csubich.spam.block at spam.subich.block.com> wrote:
>
>>>is very much within the language specification.  Indeed, the language 
>>>specification dictates that an instance variable b.a is created if one 
>>>didn't exist before; this is true no matter if type(b.a) == int, or if 
>>>b.a is some esoteric mutable object that just happens to define 
>>>__iadd__(self,type(other) == int).
>> 
>> But if it is an esoteric descriptor (or even a simple property, which is
>> a descriptor), the behaviour will depend on the descriptor, and an instance
>> variable can be created or not, as desired, along with any side effect you like.
>
>Right, and that's also language-specification.  Voodoo, yes, but 
>language specification nonetheless. :)

I guess http://docs.python.org/ref/augassign.html is the spec.
I notice its example at the end uses an old-style class, so maybe
it's understandable that when it talks about getattr/setattr, it doesn't
mention the possible role of descriptors, nor narrow the meaning of
"evaluate once" for a.x to exclude type(a).x in the setattr phase of execution.

I.e., if x is a descriptor, "evaluate" apparently means only

    type(a).x.__get__(a, type(a))

since that is semantically getting the value behind x, and so both of the ".x"s in

    type(a).x.__set__(a, type(a).x.__get__(a, type(a)).__add__(1)) # (or __iadd__ if defined, I think ;-)

don't count as "evaluation" of the "target" x, even though it means that a.x got evaluated twice
(via getattr and setattr, to get the same descriptor object (which was used two different ways)).

I think the normal, non-descriptor case still results in (optimized) probes for type(a).x.__get__
and type(a).x.__set__ before using a.__dict__['x'].

ISTM also that it's not clear that defining __iadd__ does _not_ prevent the setattr phase from going ahead.
I.e., a successful __iadd__ in-place mutation does not happen "instead" of the setattr.

Regards,
Bengt Richter



More information about the Python-list mailing list