Search code examples
pythonoopclass-method

How to initialize a class member using a classmethod


I have a class, which holds some member x (say, some data that is needed by all instances, but independent of them):

class Foo(object):
    x = 23

    # some more code goes here    

Now, the procedure of determining x became more complex plus I wanted to be able to "refresh" x at certain times, so I decided to write an extra function for it

class Foo(object):
    @classmethod
    def generate_x(cls):
        cls.x = 23

    # some more code goes here

However, this class definition lacks an initialization call of generate_x.

What I tried so far:

This does not work:

class Foo(object):

    # generate_x()     # NameError: name 'generate_x' is not defined
    # Foo.generate_x() # NameError: name 'Foo' is not defined

    @classmethod
    def generate_x(cls):
        cls.x = 23

This works but less clear, because code is used outside the class definition

class Foo(object):

    @classmethod
    def generate_x(cls):
        cls.x = 23

    # ...
Foo.generate_x()

Are there better alternatives to this? Is using @classmethod the best approach here? What I'm searching is a class-equivalent of __init__.

Considering code clarity, is there a better way than the latter to instantiate Foo.x automatically using a function?


Solution

  • One way to achieve this is by using a decorator:

    def with_x(cls):
       cls.generate_x()
       return cls
    
    @with_x
    class Foo(object):
       @classmethod
       def generate_x(cls):
          cls.x = 23
    

    (That said, I personally would just call Foo.generate_x explicitly after the class declaration, and avoid all the magic altogether.)