Unclear On Class Variables
Pierre Barbier de Reuille
pierre.barbier at cirad.fr
Fri Jan 14 03:41:47 EST 2005
Pierre Barbier de Reuille a écrit :
> Antoon Pardon a écrit :
>
>>> Well I find this a confusing behaviour on python's part. The fact
>>> that instance.field can mean something different, depending on
>>> where in a statement you find it, makes the behaviour inconsistent.
>>>
>>> I know people in general here are against declarations, but declarations
>>> could IMO provide more consistency here and thus more obvious behaviour.
>>
>>
>>
>> Well just to show how confusing python can be, the following piece of
>> code.
>>
>> | class Spam:
>> | eggs = [2, 3]
>> | | | sp1 = Spam()
>> | sp2 = Spam()
>> | | print sp1.eggs, id(sp1.eggs)
>> | print sp2.eggs, id(sp2.eggs)
>> | print '--------------------'
>> | | sp1.eggs += [4,]
>> |
>> | print sp1.eggs, id(sp1.eggs)
>> | print sp2.eggs, id(sp2.eggs)
>> | print '--------------------'
>> |
>> | Spam.eggs = [3,5]
>> |
>> | print sp1.eggs, id(sp1.eggs)
>> | print sp2.eggs, id(sp2.eggs)
>> | print '--------------------'
>>
>> Which produces:
>>
>> [2, 3] 1075958860
>> [2, 3] 1075958860
>> --------------------
>> [2, 3, 4] 1075958860
>> [2, 3, 4] 1075958860
>> --------------------
>> [2, 3, 4] 1075958860
>> [3, 5] 1075959084
>> --------------------
>>
>
> Well ... and could someone explain this behaviour ?
> I don't catch it !
>
> Pierre
Ok, I think I got it ! I speak with friends working with Python too ...
It seems that "a += l" if "a" and "l" are lists is equivalent to :
a.extend(l)
a = a
The second line could seem meaningless but it is not ! Indeed, in the
example above, the first "sp1.eggs" (the one with the extend) is a class
variable but, the second "sp1.eggs" (the one before the "=") is an
instance variable !
So, at the end, we append to get sp1.eggs and Spam.eggs references to
the same structure. But sp1.eggs is an instance variable of sp1 and no
more the class variable. To test that, it's possible to modify slightly
the code with :
|sp1.eggs += [4,]
|del sp1.eggs
Then, sp1.eggs still exists !!! But it's again the class variable ...
Ok, back to the documentation ...
In the doc, there is a special case for the use of "+=" with the class
members. IMHO, this should not be !!! But, it says that :
ob.a += b
is translated into :
ob.__setattr__( "a", ob.__getattr__("a").__iadd__(b) )
My opinion is : it would be much more simpler to explain than :
a += b <=> a.__iadd__(b); a = a
and not give any special case for class members. In both cases, the
resulting behaviour is the same, but it would be less confusing.
Then, this change of scope of variables in python is very very annoying.
Both for new and old programmers (we have both in my lab ...).
Well, I hope I got it write this time ... but this is a feature to fear !!!
Pierre
More information about the Python-list
mailing list