使用元类时 __new__ 的虚假参数

Spurious arguments to __new__ when using metaclass

我正在尝试了解 python 3.7 中的元类并具有以下代码

class Foo(type):

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        return super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        return super().__call__(cls, *args, **kwargs)


class Bar(metaclass=Foo):

    def __new__(cls, *args, **kwargs):
        print(cls)
        print(args)
        print(kwargs)
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        return super().__init__(*args, **kwargs)


b = Bar()

当我运行它时我得到输出

<class '__main__.Bar'>
(<class '__main__.Bar'>,)
{}

和错误

File "meta/main.py", line 91, in __new__
    return super().__new__(cls, *args, **kwargs)
TypeError: object.__new__() takes no arguments

该行对应于 Bar

中的 __new__ 调用

我不明白为什么要传入第二个 <class '__main__.Bar'>。如果我将 Bar 更改为不使用 Foo 元类(即更改 class Bar(metaclass=Foo): class Bar:) 我得到

<class '__main__.Bar'> 
()
{}

并且没有错误(如我所料)。感谢您的帮助

您正在调用一个额外的参数:

def __call__(cls, *args, **kwargs):
    return super().__call__(cls, *args, **kwargs)

__call__ 不是隐式静态方法,删除 cls 参数:

def __call__(cls, *args, **kwargs):
    return super().__call__(*args, **kwargs)