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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to