使用元类时对__new__的虚假参数

时间:2018-11-26 22:16:05

标签: python-3.x new-operator 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

该行对应于__new__中的Bar调用

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

class Bar:

,并且没有错误(正如我期望的那样)。感谢您的帮助

1 个答案:

答案 0 :(得分:2)

您在通话中传递了一个额外的参数:

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

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

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