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