在 python 中,有什么方法可以在定义 class 后立即自动执行 运行 功能?

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

我正在开发 class。它需要的 class 级数据将相对复杂。为了节省打字时间并最大程度地减少错误,我想通过函数定义大量此类数据。另外,即使用户还没有准备好实例化 class,我也想让这些数据可供用户使用。所以,我想知道,有没有一种方法可以在定义 class 后立即自动将这些函数设置为 运行?例如,我想要

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.

然后用户可以做类似的事情

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

你可以试试:

#file Foo.py

import numpy as np

bar = np.range(100)

class foo:
    pass

然后

# file main.py
import Foo

b = Foo.bar
foo_instance = Foo.foo()

您在模块顶层包含的任何代码都将在导入时执行。

通常它只是函数和 class 声明。但是你可以把任何代码放在顶层:

# module1.py
def foo():
  return bar

A = 100
print('You just imported module1')

然后您可以 import module1 并查看打印的消息,并且 foo.A 等于 100。

在导入时执行有副作用的代码通常不是最聪明的主意;确保你明白你在做什么,以及为什么。 (否则不做,提供初始化函数)

Class 属性在定义 class 时初始化。不需要任何功能。

import numpy as np    

class Foo:
    bar = np.range(100)
    def __init__(self):
        # etc.

如果您想要一个可以在导入之后但在实例化 class 之前调用的函数,您可以定义一个 class 函数。

class Foo:
    @classmethod
    def initialize_bar(cls):
        cls.bar = np.range(100)

然后...

>>> from foopackage import Foo
>>> Foo.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'bar'
>>> Foo.initialize_bar()
>>> Foo.bar
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
       68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])

理智/简单的处理方法是让 class 的作者明确地做到这一点。所以像:

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.

然后,每当消费者执行 import foo; my_foo_instance = foo.Foo() 时,它就已经被构建了。

您可以创建一个 metaclass 来检查 class 成员的某个标签,它会自动执行此操作,但老实说,以上内容对我和未来的读者来说都非常清楚你的class(最好不要将变量的初始化移动到看似神奇的元class foo)。

也许这个(变体 1)

def complex_data_calc():
    return range(42)

class Foo:
    bar = compex_data_calc()

    def __init__(self):
        pass

或这个(变体 2)

class Foo:
    @staticmethod
    def bar():
        return range(42)

    def __init__(self):
        pass

并用

打电话
from foopackage import Foo
Foo.bar    # variant 1
Foo.bar()  # variant 2