Search code examples
pythonclass-methodclass-attributes

How can I use a Python Class attribute as a default value for a @Classmethod?


Take a look at the code below.

I want to use the value of a as the default value for argument c in the declaration of the classmethod my_method().

How can I do it? The example below fails.

>>> class X:
...     a = 'hello'
...     def __init__(self, b):
...         self.b = b
...     @classmethod
...     def my_method(cls, c=X.a):
...         print 'cls.a = {}'.format(cls.a)
...         print 'c = {}'.format(c)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in X
NameError: name 'X' is not defined

Solution

  • It really depends what you want, but one way to get what you seem to want is to do it like this.

    class X:
        a = 'hello'
        def __init__(self, b):
            self.b = b
        @classmethod
        def my_method(cls, c=None):
            if c is None:
                c = X.a
            print('cls.a = {}'.format(cls.a))
            print('c = {}'.format(c))
    
    X.my_method()
    

    Make the default None and check for None in the function body, assigning to c if it is found to be None. If you ever wanted None to be a valid argument for the function then it wouldn't work, but that doesn't seem likely.

    This idiom is often used in python to avoid the pitfalls mutable default argument, but here it delays the assignment from X.a until after X has actually been defined.

    It also means that if you change X.a then my_method will pick up the new value. You may or may not want that.