gpt4 book ai didi

python - 动态 __init_subclass__ 方法的参数绑定(bind)

转载 作者:行者123 更新时间:2023-12-01 09:28:44 24 4
gpt4 key购买 nike

我正在尝试让类装饰器工作。装饰器将向其所应用的类添加一个 __init_subclass__ 方法。

但是,当该方法动态添加到类中时,第一个参数不会绑定(bind)到子类对象。为什么会发生这种情况?

举个例子:这是可行的,下面的静态代码是我想要得到的结果的一个示例:

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__ 方法,子类不会绑定(bind)到第一个参数:

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'

为什么会发生这种情况?我该如何做到这一点并使绑定(bind)以正确的方式工作?

最佳答案

__init_subclass__ is an implicit classmethod .

可能无法使用零参数 super(如果您想了解原因,请阅读 here),但您应该能够在装饰器本身内部显式绑定(bind) super。

def decorator(Cls):
def __init_subclass__(subcls, **kwargs):
print(f'init subclass {Cls!r}, {subcls!r}, {kwargs!r}')
super(Cls, subcls).__init_subclass__(**kwargs)
Cls.__init_subclass__ = classmethod(__init_subclass__)
return Cls

@decorator
class C:
pass

class D(C):
pass

关于python - 动态 __init_subclass__ 方法的参数绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50137242/

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