Null Disquisition

Python, AWS, Grad School, and your face

Python static class members and You

with one comment

After getting yelled at for not grading my student’s homework, I decided to ignore the threatening emails and continue doing what I feel like. Undergrads, know this: TAs don’t really care about you – sorry. I was debugging some code built on top of my awesome HTMLParser, and kept having a really frustrating problem. Some of my class variables were not getting reset during the init call. So I poke around and after a while discover (buried in my libraries)

class Foo:
    a = True
    b = []
    c = []
    def init(self):
        ""
It seems the class members a, b, and c are not getting reset when I instanciate becasue, quite simply, I am not resetting them in init. I originally put them there for prettiness (self.a, self.b, self.c is so cumbersome), and moving them back into init fixed my problem.

A little more digging reveals what is going on here. If you define a variable outside of a class method, the variable is implicitly made static.

class Foo:
    a = "Hello"
print Foo.a
>> Hello
These static members are accessed just like regular members, with the “self” object. For things like str, int, float, the value will seem to be reset when you create a new instance of the class. But what’s really happening is when you alter the static variable, you are actually creating a new class variable (in memory) which overrides the static for the duration of that object. This is not true for lists and dicts. I assume this is because Python uses pointers for array-like structures and the static member is just a pointer here. So when you alter the static list (via getitem, append, remove, et al.) you are operating on the pointer, not a copy of the list.
class Foo:
    a = []
    def init(self):
        print self.a
        self.a.append(1)
f = Foo()
f = Foo()
f = Foo()
>> []
>> [1]
>> [1,1]
Depending on how you’re structuring your code (or how good at Python you are) you might want this functionality. For me though, this was not the case, so I put everything back in init. Another good thing to point out is Python has a very convienent syntax for making a copy of an array.
    a = [1,2,3,4]
    b = a
    c = a[:]
    b[0] = 5
    c[0] = 6
    print a
    print b
    print c
    >> [5,2,3,4]
    >> [5,2,3,4]
    >> [6,2,3,4]
Sometimes I miss pointers, but not really. -David

Written by david

December 4th, 2008 at 8:45 pm

Posted in python

Tagged with ,