gpt4 book ai didi

python - 在 __new__ 中使用 object.__new__ 有什么缺点?

转载 作者:太空狗 更新时间:2023-10-30 00:05:41 27 4
gpt4 key购买 nike

编码异常类,我遇到了这个错误:

TypeError: object.__new__(A) 不安全,使用 Exception.__new__()

这里有一个类似的问题: TypeError: object.__new__(int) is not safe, use int.__new__() .所以 __new__ 被弃用的原因如下:

[Python-Dev] __new__ deprecation

Guido van Rossum

"The message means just what it says. :-) There's no point in calling object.__new__() with more than a class parameter, and any code that did so was just dumping those args into a black hole."

但是我在 3.3 中收到的“不安全”的警告是可怕的。我试图理解使用 object.__new__ 的含义,让我们考虑这个例子:

>>> class A(Exception):
... def __new__(cls, *args):
... return object.__new__(A)
...
>>> A()
TypeError: object.__new__(A) is not safe, use Exception.__new__()

惨败。另一个例子:

>>> class A(object):
... def __new__(cls, *args):
... return object.__new__(A)
...
>>>
>>> A()
<__main__.A object at 0x0000000002F2E278>

工作正常。尽管 object 是一个内置类,就像 Exception 就它们的角色而言,它们具有内置类的特性。现在对于 Exception,第一个示例引发了 TypeError,但是对于 object,它不会吗?

(a) 使用 object.__new__ 的缺点是什么使 Python 引发错误(TypeError:... is not safe...) 在第一个例子中?

(b) 在调用 __new__ 之前 Python 执行什么样的检查?或者:在第一个示例中导致 Python 引发错误的条件是什么?

最佳答案

调用object.__new__没有问题,但是不调用Exception.__new__就有问题

Exception 类的设计方式使得它的 __new__ 必须被调用是至关重要的,所以如果没有调用它就会提示。

有一个问题,为什么这种情况只发生在内置类中。事实上,Python 对每个编程为执行此操作的类都执行此操作。

下面是自定义类中相同机制的简化穷人实现:

class A(object):
def __new__(cls):
rtn = object.__new__(cls)
rtn.new_called = True
return rtn

def __init__(self):
assert getattr(self,'new_called',False), \
"object.__new__ is unsafe, use A.__new__"

class B(A):
def __new__(cls):
return object.__new__(cls)

现在:

>>> A()
<__main__.A object at 0x00000000025CFF98>

>>> B()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in __init__
AssertionError: object.__new__ is unsafe, use A.__new__

作为旁注,问题中的这个例子实际上有两个错误:

>>> class A(Exception):
... def __new__(cls, *args):
... return object.__new__(A)

首先是 __new__ 是在 object 上调用的,因此忽略了 Exception.__new__

另一个,同样严重的是 A 被传递给 __new__ 而不是 cls,这阻碍了从 继承的所有类A.

看这个例子:

class A(object):
def __new__(cls):
return object.__new__(A) # The same erroneous line, without Exception

class B(A):
pass

现在 B() 不会创建 B 的实例:

>>> B()
<__main__.A object at 0x00000000025D30B8>

关于python - 在 __new__ 中使用 object.__new__ 有什么缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39515463/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com