assigning class variable as default value to class method argument

tomasz74 picture tomasz74 · Mar 3, 2013 · Viewed 31.1k times · Source

I would like to build a method inside a class with default values arguments taken from this class. In general I do filtering on some data. Inside my class I have a method where normally I pass vector of data. Sometimes I don't have the vector and I take simulated data. Every time I do not pass a particular vector I would like to take simulated data by default. I thought it should be an easy construction where inside my method definition I say a=self.vector. But for some reason I have an error NameError: name 'self' is not defined. The simplified construction is:

class baseClass(object):  # This class takes an initial data or simulation
    def __init__(self):
        self.x = 1
        self.y = 2

class extendedClass(baseClass): # This class does some filtering
    def __init__(self):
        baseClass.__init__(self)
        self.z = 5
    def doSomething(self, a=self.z):
        self.z = 3
        self.b = a

if __name__ == '__main__':
    a = extendedClass()
    print a.__dict__
    a.doSomething()
    print a.__dict__

An output I expected should be:

{'y': 2, 'x': 1, 'z': 5}
{'y': 2, 'x': 1, 'z': 3, 'b': 5}

I tried default assignment as def doSomething(self, a=z): obviously it doesn't work ever. As far as I understand self.z is visible in this scope and should not be a problem to have it as a default value. Don't know why I have this error and how to do it. This is probably an easy question, but I try to figure it out or find the solution with no lack for sometime already. I found similar questions only for other languages.

Answer

Daniel Roseman picture Daniel Roseman · Mar 3, 2013

Your understanding is wrong. self is itself a parameter to that function definition, so there's no way it can be in scope at that point. It's only in scope within the function itself.

The answer is simply to default the argument to None, and then check for that inside the method:

def doSomething(self, a=None):
    if a is None:
        a = self.z
    self.z = 3
    self.b = a