direct initialization of class attributes vs. declarations w/in __init__

digitalorganics at gmail.com digitalorganics at gmail.com
Sun Jun 11 13:35:14 EDT 2006


Wait a minute! It doesn't explain my bugs. I've got "class variables"
acting like instance variables. What's weirder is that this behavior
occurs on my computer (in both of my installed WinXP copies) but not on
my laptop (WinXP Pro).

See the following test:

class Boo:
    jerk = "yes"

    def killjerk(self):
        self.jerk = self.jerk + "no"
        print self.jerk
        print self.__class__.jerk

bing = Boo()
bing.killjerk()

outputs:

yesno
yes

At first, I thought that self.jerk was resolving to the class attribute
instead of creating a new variable (w/ a differing scope). But we can
see that there are actually two variables because a direct reference to
self.__class__.jerk returns "yes", not yesno (what we would get if
self.jerk pointed to the same data/object as self.__class__.jerk). Yet,
it's treating self.jerk as a combination of the two (it always add the
class attribute to the instance attribute). Is this normal behavior??
It doesn't work this way on my laptop...

Perhaps you can see why I'd be confused!

Thanks.

digitalorganics at gmail.com wrote:
> Ah, you've brought me much clarity Diez, thank you. That would explain
> some "bugs" I've been having...
>
>
> Diez B. Roggisch wrote:
> > digitalorganics at gmail.com schrieb:
> > > What's the difference between initializing class variables within the
> > > class definition directly versus initializing them within the class's
> > > __init__ method? Is there a reason, perhaps in certain situations, to
> > > choose one over the other?
> >
> > You are confusing class variables with instance variables. The former
> > are what you can initialize inside the class-statement. However, they
> > are shared amongst _all_ instances. Consider this little example:
> >
> > class Foo(object):
> >      FOO = 1
> >      BAR = []
> >
> >      def __init__(self, FOO):
> >          self.FOO = FOO
> >          self.BAR.append(FOO)
> >
> >      def __repr__(self):
> >          return "FOO: %r\nBAR: %r\n" % (self.FOO, self.BAR)
> >
> >
> > f1 = Foo(1)
> > print f1
> > f2 = Foo(2)
> > print f2
> > print f1
> >
> >
> > ------
> > meskal:~/Projects/CameraCalibrator deets$ python2.4 /tmp/test.py
> > FOO: 1
> > BAR: [1]
> >
> > FOO: 2
> > BAR: [1, 2]
> >
> > FOO: 1
> > BAR: [1, 2]
> >
> >
> > -----
> >
> > As you can see, the list BAR is shared. And you can also see that
> > _assigning_ to something like this:
> >
> > self.FOO
> >
> > will create an instance-variable. Even if a variable of the same name
> > existed on the class before!
> >
> > Which is precisely the difference between using variable initialization
> > in __init__ and inside the class-statement.
> >
> > BTW,
> >
> > self.__class__.FOO = value
> >
> > will set class-variables inside a method. Just if you wondered.
> > 
> > Diez




More information about the Python-list mailing list