[Tutor] Change to Class-level Variable

Steven D'Aprano steve at pearwood.info
Mon Oct 4 00:33:24 CEST 2010


On Mon, 4 Oct 2010 09:06:39 am Robert wrote:

> Why is "f1" not affected by the Class-level variable change below ?


The Python terminology is "attribute", not variable. You have class 
attributes and instance attributes.


> >>> class Foo( object ):
> ...     myid = 'Foo'
> ...     def __init__( self ):
> ...        pass

That __init__ method does nothing. Leave it out:

class Foo(object):
    myid = 'Foo'


> >>> f1 = Foo()
> >>> f2 = Foo()
> >>> f1.myid = 'Bar'

This creates an instance attribute called myid which masks the class 
attribute.


> >>> Foo.myid = 'SPAM'

This directly changes the class attribute.


Think of it this way: when you lookup an attribute, Python searches:

* the instance
* the class
* any superclasses

in that order, and returns the first matching value it finds. When you 
set an attribute, Python follows the same pattern, but naturally the 
first attempt (instance) will always succeed. (Note: this may not be 
what Python *actually* does, but conceptually it has always helped me 
reason about the behaviour.)

Python won't let you accidentally modify a class attribute. You have to 
do it explicitly. Here are three ways to do it:

type(f1).myid = 'Bar'
f1.__class__.myid = 'Bar'
Foo.myid = 'Bar'


(You might be able to do some sort of metaclass magic to change this 
behaviour, but consider that *very* advanced.)


-- 
Steven D'Aprano


More information about the Tutor mailing list