Search code examples
pythonpython-2.7oopclass-method

Use classmethod as default argument


If I do something like this:

class MyClass(object):
    def __init__(self, a=MyClass.f):
         self.a = a

    @classmethod
    def f():
         print 'tump drump'

I get the following error:

NameError: name 'MyClass' is not defined

Obviously, I could do this:

class MyClass(object):
    def __init__(self, a=None):
         if a is None:
              self.a = MyClass.f
         else:
              self.a = a

But is there a more elegant way to use a classmethod as default argument of a class method?


Solution

  • No, there isn't, because the functions are created before the class object is. There is not class to reference here, and the use of a sentinel (like None) is the correct way to do this.

    Note that there is no need to use an else suite if you assign to a rather than self.a in the if suite:

    class MyClass(object):
        def __init__(self, a=None):
             if a is None:
                  a = MyClass.f
             self.a = a
    

    or you could use a conditional expression:

    class MyClass(object):
        def __init__(self, a=None):
             self.a = MyClass.f if a is None else a
    

    or even:

    class MyClass(object):
        def __init__(self, a=None):
             self.a = a or MyClass.f
    

    if all you need to support is truthy objects (function objects always are 'true' in a boolean context, for example).