Search code examples
pythonclassinstantiation

In python, any way to automatically run functions as soon as a class is defined?


I am developing a class. The class-level data it will need is going to be relatively complex. To save typing and minimize mistakes, I would like to define a good bit of this data through functions. Also, I would like to make this data available to the user even if they aren't ready to instantiate the class. So, I wonder, is there a way to get these functions to run automatically as soon as the class is defined? As an example, I want something like

import numpy as np    

def class foo:

        @this_should_run_before_instantiation
        def define_bar:
            bar = np.range(100)

       @this_should_also_run_before_init
       def define_something_really complicated:
            bleh = # something that is too complicated for a single line or lambda

        def __init__(self):
            # etc.

So then the user can do something like

>>>from foopackage import foo
>>>foo.bar
array([ 0,  1,  2,  3,  4,  5,  ... #etc.
>>>foo.bleh
< whatever bleh is ... >

Solution

  • The sane / simple way to handle this is for you the author of the class to do this explicitely. So something like:

    class Foo:
        @classmethod # don't have to be but will likely benefit from being classmethods...
        def _define_something_really_complicated(cls):
            ...
        @classmethod
        def _define_something_else_really_complicated(cls):
            ...
        @classmethod
        def _build(cls):
            cls._define_something_really_complicated()
            cls._define_something_else_really_complicated()
            ...
        def __init__(self):
            ...
    
    Foo._build() # where your module is defined.
    

    Then whenever a consumer does import foo; my_foo_instance = foo.Foo() it will already be built.

    You could create a metaclass which inspects the class members for some tag and it will automatically do this, but honestly, the above makes everything very clear to me and to future readers of your class (best not to move initialization of variables into magical-seeming metaclass foo).