Null Disquisition

Python, AWS, Grad School, and your face

Archive for the ‘programming’ tag

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 ,