3

I have a class function that takes 4 arguments, all class member variables in practice. Usually only one of these arguments is modified at a time and the rest of the time the would-be defaults (current values of the class member variables) are passed to the function/written out even though they aren't changing.

I thought the best would be to make these class member variables the defaults, but I'm having a hard time getting the best syntax. The following code produces behavior I desire - using a class member variable as a default parameter to a function. But it's ugly:

class test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def testfunc(self, param = None):
        if not param:
            param = self.a
        print(param)


if __name__ == '__main__':
    a1 = test(1, 3)
    a1.testfunc()
    a2 = test(5, 5)
    a2.testfunc()
   #(prints 1 and 5 when called)

I would like to use the following:

    def testfunc(self, param = self.a):
        print(param)

But this gives the error:

NameError: name 'self' is not defined

What's a better way to do this?

sunny
  • 3,853
  • 5
  • 32
  • 62

2 Answers2

4

Your first attempt is pythonic, the only thing I would change is the test:

 def testfunc(self, param = None):
        if param is None:
            param = self.a
        print(param)

The problem with testing for False is that zero and an empty container (including an empty string) all resolve to False.

If you have a large number of these, see Understanding kwargs in Python

Community
  • 1
  • 1
cdarke
  • 42,728
  • 8
  • 80
  • 84
0

If your function takes 4 arguments, and all 4 are optional and have matching properties on the object itself, then you can make this simpler by using keyword arguments:

def testfunc(self, **kwargs):
    a, b, c, d = [kwargs.get(name, getattr(self, name)
                  for name in ('a', 'b', 'c', 'd')]

You'd then need to call this using keyword arguments:

obj.testfunc()  # all values are defaults
obj.testfunc(a=1)  # a=1, all other values are defaults
obj.testfunc(b=2, d=5)  # etc.
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135