Class properties and object properties

Diez B. Roggisch deets at nospam.web.de
Mon Oct 6 16:00:11 CEST 2008


SuperZE wrote:

>> Because you declare myList to be a *class*-level variable, which means
>> *all* instances of that class (a and b in your case) *share* it. Python
>> does not declare *instance* variables the way you do.
>>
>> Instead, do this:
>>
>> class Foo(object):
>> def __init__(self):
>> self.myList = []
> 
> 
> Interesting, but that does not explain the difference in the behavior
> of myList and myInt

Sorry, I forgot that.

The reason is simple - lists are mutable. Numbers aren't. And when you
*assign* to an instance a value, it will be set on the instance, not on the
class.

The same happens (as you've already seen for yourself) when you do

a.myList = []

as this creates a new list, stored only on a.

 
> Both were class-level variables, as far as I can see, and therefor a
> and b should also share it

Nope. To change it, you need to do

Test1.myInt = 5

The thing is that the lookup triggered by getattr/dotted notation goes
roughly like this:

1) try to find the attribute (value *or* method! Python doesn't distinguish)
in the instance itself.

2) if not found there, look at the class.

3) if not found there, look at the base-classes in the method resolution
order (MRO)

There are some other things involved - descriptor protocol calls on the
class-level lookups - but that's not relevant for the problem at hand.

OTOH, when setting with setattr/dotted notation, it will always set on the
object passed.

Diez



More information about the Python-list mailing list