python - 动态 __init_subclass__ 方法的参数绑定
问题描述
我正在尝试让班级装饰员工作。装饰器将向__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(如果您想了解原因,请阅读此处),但您应该能够在装饰器本身内显式绑定 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
推荐阅读
- django - Django ORM:带有简单“分组依据”的查询集
- python-3.x - 单元测试正确的“继续”行为
- node.js - 是否可以用电子的 net 模块替换 requestjs 模块
- c# - 应用程序部署后在 StartUp.cs 中只运行一次函数
- python-3.x - 从任务创建函数返回异步回调结果
- c# - 使用通过 Xamarin 的意图参数重定向到应用程序
- swift - Google Places Picker 不再工作,说:iOS 的 Places API 未启用。请参阅开发人员指南
- datatable - Google Material Design - 数据表过滤栏中的复杂条件过滤芯片
- reactjs - 在 React 中获取单击元素的道具
- python - setup.py 是否真的将包加载到 GCP 数据流?