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