Python (AttributeError:_输入_)在使用_新_魔术方法时

Python (AttributeError:_输入_)在使用_新_魔术方法时,python,magic-methods,Python,Magic Methods,我正在尝试使用\uuuuu new\uuuuu方法在处理它之前检查参数有效性(str),因此我执行以下操作: class foo: def __new__(cls, argument): if not isinstance(argument, str): raise TypeError('argument must be str') print("passed __new__") def __init__(self, a

我正在尝试使用
\uuuuu new\uuuuu
方法在处理它之前检查参数有效性(str),因此我执行以下操作:

class foo:

    def __new__(cls, argument):
        if not isinstance(argument, str):
            raise TypeError('argument must be str')
        print("passed __new__")

    def __init__(self, argument):
        self.argument = argument
        print("passed __init__")

    def __enter__(self):
        print("passed __enter__")

    def __exit__(self, *args):
        print("passed __exit__")
然后,当我使用
关键字调用它时,它调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
我得到以下输出:
我期望这个输出:

我注意到在完全删除
\uuuuuu新方法时;它会起作用的。为什么使用
\uuuu new\uuuu
会打破这一点?我怎样才能让它在
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class foo:

    def __new__(cls, argument):
        if not isinstance(argument, str):
            raise TypeError('argument must be str')
        print("passed __new__")
        return super().__new__(cls)

    def __init__(self, argument):
        self.argument = argument
        print("passed __init__")

    def __enter__(self):
        print("passed __enter__")

    def __exit__(self, *args):
        print("passed __exit__")
您可以想象,
\uuuuuuuuuuuuuuuuuuuuuuuuu
的定义如下

def __call__(cls, *args, **kwargs):
    obj = cls.__new__(*args, **kwargs)
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)
    return obj

覆盖
\uuuu new\uuuu
意味着您希望更改实例的创建方式,而覆盖
\uuuuuu init\uuuuu
意味着您希望更改已创建实例的初始化方式。在这种情况下,如果参数的类型错误,您可以避免创建一个新实例。

为什么不返回super()。\uuuu new\uuuu(cls)
引发一个缺少参数的异常,因为
参数不存在?因为
super()。\uu new\uuuuuuuuuuuu>没有调用
foo.\uu new\uuuuuu
;它正在调用(在本例中)
对象。\uuuuu new\uuuuu
,除类之外不需要任何其他参数。您没有正确创建对象。new需要调用super()。\uuuu new\uuuu(cls,参数),然后返回实例super()。\uuuuu new\uuuuu()返回。
passed __new__
passed __init__
passed __enter__
i am between __enter__ and __exit__, damn!
passed __exit__
class foo:

    def __new__(cls, argument):
        if not isinstance(argument, str):
            raise TypeError('argument must be str')
        print("passed __new__")
        return super().__new__(cls)

    def __init__(self, argument):
        self.argument = argument
        print("passed __init__")

    def __enter__(self):
        print("passed __enter__")

    def __exit__(self, *args):
        print("passed __exit__")
type.__call__(foo, 'test')
def __call__(cls, *args, **kwargs):
    obj = cls.__new__(*args, **kwargs)
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)
    return obj