initializing mutable class attributes

Benjamin Niemann b.niemann at betternet.de
Mon Aug 30 09:35:05 CEST 2004


That's the way it is supposed to work. Instance attributes have to be 
initialized via self.foo=..., usually in __init__() which in turn is 
*STRONGLY* advised to class its parents __init__() - or you create 
instance attributes 'on-the-fly' when they are used for the first time 
(useful technique for mixin classes without constructor). Class 
attributes are initialized once for the class and are shared between 
instances.
"self.attr1=data" in Father.foo() doesn't "override" the Father.attr1 
attribute you defined before. It creates an instance attribute that 
shadows Father.attr1!
Both attribute assignments in Father are OK - if you treat them as class 
attributes. They won't become instance attributes by hidden magic.

Dan Perl wrote:
> There is something with initializing mutable class attributes that I am
> struggling with.  I'll use an example to explain:
>     class Father:
>         attr1=None   # this is OK
>         attr2=[ ]        # this is wrong
>         def foo(self, data):
>             self.attr1=data
>             self.attr2.append(data)
> The initialization of attr1 is obviously OK, all instances of Father
> redefine it in the method foo.  But the initialization of attr2 is wrong
> because all the instances of Father end up sharing the same value.  Maybe
> that is desired sometimes, but usually it is just a bug.
> 
> So the only solution I see to this is to initialize attr2 in __init__:
>     class Father:
>         attr1=None
>         def __init__(self):
>             self.attr2=[ ]
> 
> This is already awkward because there is such a difference between attr1 and
> attr2.  But moreover, I think this forces subclasses of Father to do
> something like this:
>     class Child (Father):
>         def __init__(self):
>             Father.__init__(self)
>             self.attr3=[ ]
> 
> I find this even more awkward because many people will forget to do it.
> Clearly, this is then a more general issue with __init__, but I think it is
> accentuated by the fact that you HAVE TO HAVE __init__ in order to
> initialize attributes that are mutable.
> 
> Is there something I don't know here and there is a better way to do this in
> Python?  I would like to get a better solution or otherwise start a
> discussion.




More information about the Python-list mailing list