Ложные аргументы __new__ при использовании метакласса - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь узнать о метаклассах в 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): на class Bar:), я получаю

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

и никаких ошибок (как я и ожидал).Спасибо за любую помощь

1 Ответ

0 голосов
/ 27 ноября 2018

Вы передаете дополнительный аргумент для вызовов:

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

__call__ не является неявным статическим методом, отбросьте этот cls аргумент:

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