Overriding class variables in python

BorrajaX picture BorrajaX · Jan 21, 2011 · Viewed 14.1k times · Source

I'm trying to understand a bit how Python (2.6) deals with class, instances and so on, and at a certain point, I tried this code:

#/usr/bin/python2.6

class Base(object):
    default = "default value in base"

    def __init__(self):
        super(Base, self).__init__()

    @classmethod
    def showDefaultValue(cls, defl = default):
        print "defl == %s" % (defl)


class Descend(Base):
    default = "default value in descend"

    def __init__(self):
        super(Descend, self).__init__()

if __name__ == "__main__":
    Descend.showDefaultValue()

The output is: "default value in base"

I was wondering why the "default" field is not overwirtten by the Descend class... Is there any way to overwrite it? Why isn't it being overwritten?

Any hint (or link to an explanatory page will be appreciated). Thank you!

Answer

Dirk picture Dirk · Jan 21, 2011

The class variable is being overwritten. Try

@classmethod
def showDefaultValue(cls):
    print "defl == %s" % (cls.default,)

The reason your way doesn't work has more to do with the way Python treats default arguments to functions than with class attributes. The default value for defl is evaluated at the time Python defines the binding for showDefaultValue and this is done exactly once. When you call your method the default value used is what was evaluated at the time of definition.

In your case, defl was bound to the value of the default variable as it was during the execution of the class body form of Base. Regardless of how you call showDefaultValue later on (i.e., whether via Base or via Descend) that value remains fixed in all subsequent invocations of showDefaultValue.