在 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
我正在开发 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