gpt4 book ai didi

python - 有没有办法在不使用 __init__ 的情况下在实例初始化时自动运行方法?

转载 作者:行者123 更新时间:2023-11-28 22:10:23 27 4
gpt4 key购买 nike

我正在用 Pytest 编写一些单元测试。如果我希望自动收集它们,我必须避免使用 __init__ 构造函数。 (如果有办法让 Pytest 使用 __init__ 构造函数收集测试,我会把它作为另一个有用的答案。)

我的单元测试有一些共同的变量和方法。现在我有基测试类 TestFoo、子测试类 TestBar(TestFoo) 和孙测试类 TestBaz(TestBar)。由于我没有 init 方法,现在我正在调用一个 setup() 方法,该方法将一组变量分配给类实例,作为每个测试方法的一部分。

看起来像:

Class TestBaz(TestBar):
def setup():
super().setup()
# do some other stuff

def test_that_my_program_works(self):
self.setup()
my_program_works = do_stuff()
assert my_program_works

但这很丑陋,我想知道是否有办法解决它。我开始工作的一件事——我制作了这个装饰器函数来装饰每个方法:

def setup(cls):
def inner_function(func):
@wraps(func)
def wrapper(*args, **kwargs):
cls.set_up()
return func(*args, **kwargs)
return wrapper
return inner_function

但是

@setup
def test_that_my_program_works():

并没有那么好。当我意识到根本上我不想或不需要包装每个方法时,我有点在阅读有关元类的杂草并试图弄清楚如何更安静地包装每个方法。我只想要一个在类初始化时自动执行的方法。我想要没有 __init____init__

有办法吗?

最佳答案

正如您所看到的,py.test 有其他方法来运行类范围方法的设置。您可能会运行它们,因为它们保证在每个(测试)方法调用之间的正确时间点运行 - 因为人们无法控制何时py.test 实例化这样一个类。

作为记录,只需在类中添加一个setup 方法(方法名称全部小写),如:

class Test1:
def setup(self):
self.a = 1
def test_blah(self):
assert self.a == 1

但是,正如您询问的有关元类的问题,是的,元类可以创建“等同于 __init__ 的自定义方法”。

当创建一个新对象时,即在 Python 中实例化类时,就好像调用了类本身。内部发生的是调用元类的 __call__ 方法,并传递参数以创建实例。

此方法然后运行传递这些参数的类的__new____init__ 方法,并返回__new__ 返回的值。

type 继承的元类可以覆盖 __call__ 以添加额外的 __init__ - 就像调用一样,代码就是:

class Meta(type):
def __call__(cls, *args, **kw):
instance = super().__call__(*args, **kw)
custom_init = getattr(instance, "__custom_init__", None)
if callable(custom_init):
custom_init(*args, **kw)

return instance

我已经在我用 pytest 运行的文件中的一个小类中尝试了这个,它确实有效:

class Test2(metaclass=Meta):
def __custom_init__(self):
self.a = 1
def test_blah(self):
assert self.a == 1

关于python - 有没有办法在不使用 __init__ 的情况下在实例初始化时自动运行方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56821603/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com