Wednesday, April 6, 2011

A word of caution for C# (and C++) developers using Python: to declare a class member variable

Consider the following Python code


class A:
    __dic = {}
    def populate(self):
        self.__dic["A"] = "a"
        self.__dic["B"] = "b"
    def dump(self):
        print self.__dic

a1 = A()
a2 = A()
a1.populate()
a2.dump()

What’s the result of the code? Well, it’s “{‘A’:’a’, ‘B’:’b’}” instead of empty dictionary as you may have expected.

It turns out that when you use above syntax __dic is actually defined as a static member of the class so it’s actually shared by all instances! To properly define an instance variable, you need to declare the variable within __init__() method of the class and prefix your variable with “self.”, as shown below:


class A:
    def populate(self):
        self.__dic = {}
        self.__dic["A"] = "a"
        self.__dic["B"] = "b"
    def dump(self):
        print self.__dic

a1 = A()
a2 = A()
a1.populate()
a2.dump()

What’s confusing is that simple types such as strings and numbers seem to have a different behavior:


class A:
    __val = "ABC"
    __num = 12345
    def populate(self):
        self.__val = "DEF"
        self.__num = 45678
    def dump(self):
        print self.__val
        print self.__num

a1 = A()
a2 = A()
a1.populate()
a1.dump()
a2.dump()

In above code, both __val and __num act as instance variables  because dump of a1 shows “DEF” and “45678” while dump of a2 shows “ABC” and “12345”.

0 comments:

Post a Comment