我正在尝试让类装饰器起作用。该装饰器将在应用于的类中添加一个__init_subclass__
方法。
然而,当将该方法动态添加到类中时,第一个参数未绑定到子类对象。为什么会发生这种情况?
例如:这可以正常工作,下面的静态代码是我要达到的目标的示例:
class C1:
def __init_subclass__(subcls, *args, **kwargs):
super().__init_subclass__(*args, **kwargs)
print(f"init_subclass -> {subcls.__name__}, {args!r}, {kwargs!r}")
测试:
>>> D = type("D", (C1,), {})
init_subclass -> D, (), {}
然而,如果我动态添加
__init__subclass__
方法,子类将不会绑定到第一个参数:def init_subclass(subcls, **kwargs):
super().__init_subclass__(**kwargs)
print(f"init_subclass -> {subcls.__name__}, {args!r}, {kwargs!r}")
def decorator(Cls):
Cls.__init_subclass__ = init_subclass
return Cls
@decorator
class C2:
pass
测试:
>>> D = type("D", (C2,), {})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: init_subclass() missing 1 required positional argument: 'subcls'
为什么会出现这种情况,我应该如何操作才能使绑定正常工作?
super()
函数中subcls
参数的需求吗?如果没有它,我会得到运行时错误。参数不应该是C2
吗...? - Ricksuper(C2, subcls)
,我有点粗心。当Cls
还不存在时,无参super工作的方式(使用__class__
单元格)使得这个操作变得棘手,但我认为你可以在装饰器中使用闭包,看看编辑后的效果如何,然后告诉我它的运行情况(未经测试)。 - wimexec
和代码字符串构建,它也能正常工作。 - Rick