在Python 3.6中将ABCMeta与__init_subclass__组合时的TypeError

So8*_*res 10 python python-3.6

我正在尝试将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()
Run Code Online (Sandbox Code Playgroud)

运行时产生以下结果:

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'
Run Code Online (Sandbox Code Playgroud)

如果Abstracted不使用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()
Run Code Online (Sandbox Code Playgroud)

任何人都可以确认这是Python 3.6 abc模块和/或__init_subclass__实现中的错误吗?(我可能使用了__init_subclass__错误.)有没有人有解决方法?

use*_*ica 6

这是一个错误abc.ABCMeta,因为设计中的疣__init_subclass__.我建议报告它.

现在几乎所有存在的元类都应该传递意外的关键字参数,super().__new__因此type.__new__可以将它们传递给__init_subclass__,但是ABCMeta和其他大量的元类还没有这样做.关键字参数abc.ABCMeta.__new__扼杀x而不是传递它,导致您看到的异常.

尝试将__init_subclass__关键字参数与尚未针对新设计​​更新的元类使用是行不通的.您必须等待用于修补的元类.