我正在尝试使用Python 3.6的新 __init_subclass__
功能 (PEP 487) 与abc
模块一起使用,但它似乎不起作用。以下是代码:
from abc import ABCMeta
class Initifier:
def __init_subclass__(cls, x=None, **kwargs):
super().__init_subclass__(**kwargs)
print('got x', x)
class Abstracted(metaclass=ABCMeta):
pass
class Thingy(Abstracted, Initifier, x=1):
pass
thingy = Thingy()
运行时产生以下结果:
Traceback (most recent call last):
File "<filename>", line 10, in <module>
class Thingy(Abstracted, Initifier, x=1):
TypeError: __new__() got an unexpected keyword argument 'x'
如果抽象类没有使用ABCMeta
元类,一切都正常工作。
这个错误非常强大,例如,以下代码仍然会因为类似的类型错误而失败(可能是因为元类的__new__
在类实例化时运行,而父类的__new__
直到对象实例化时才运行)。
from abc import ABCMeta
class Initifier:
def __new__(cls, name, bases, dct, x=None, **kwargs):
return super().__new__(cls, name, bases, dct, **kwargs)
def __init_subclass__(cls, x=None, **kwargs):
super().__init_subclass__(**kwargs)
print('got x', x)
class Abstracted(metaclass=ABCMeta):
pass
class Thingy(Initifier, Abstracted, x=1):
pass
thingy = Thingy()
有人能确认这是否是Python 3.6中abc
模块和/或__init_subclass__
实现中的一个错误吗?(我可能在错误地使用__init_subclass__
。)有人有解决方法吗?
__init_subclass__
设计中有一个有趣的交互。现在存在的几乎每个元类都应该将意外的关键字参数传递给super().__new__
,以便type.__new__
可以将它们传递给__init_subclass__
,但是ABCMeta和可能还有许多其他元类没有这样做。 - user2357112Initifier
中添加对__new__
的调用,并在其中处理x
参数,会怎样呢? - Rick