gpt4 book ai didi

python - 为什么 sympy 覆盖 `__new__` 而不是 `__init__` ?

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

sympy 中的每个对象是 Basic 的子类类,他们都使用 __new__ 而没有 __init__,而且大多数情况下都是类似

def __new__(cls, some, parameter, **others):
obj = parentclass.__new__(cls, **others)
obj.some = some
obj.parameter = parameter
return obj

像这样使用__init__有什么区别

def __init__(self, some, parameter, **others):
parentclass.__init__(self, **others) # or super().__init__(...)
self.some = some
self.parameter = parameter

?

最佳答案

看看Number .他们希望对象的类是灵活的。 Number(...) => Int/Float/... __init__ 无法实现。

此外,__init__ 将获得 __new__ 的参数,但您不需要原始参数,请参阅 matexpr.py或者您需要它们适应 __new__ 已经做过的事情(例如 for __reduce__ )。

大多数对象都定义了它们自己的__slots__,所以有固定的属性可以分配给它们。可以在 __new____init__ 中完成赋值。我不认为需要打开一个新的 __init__ 来设置它们而不做其他操作 - 正如 Martijn Pieters 和 user4815162342 [source]指出对象是不可变的。

有时 __init__ 不被调用,如果你改变类,一次或两次:

class X(object):
def __new__(self): # sorry but self is the class I apologize!
obj = object.__new__(Y)
return obj
def __init__(self):
print 1

>>> class Y(object):
def __init__(self):
print 2
>>> X() # no __init__ call, limiting you to stay in the class hierarchy
<__main__.Y object at 0x7f287e769350>
>>> class Y(X):
def __init__(self):
print 2


>>> X() # one __init__ call
2
<__main__.Y object at 0x7f287e7693d0>
>>> class X(object):
def __new__(self):
obj = Y()
return obj
def __init__(self):
print 1


>>> class Y(X):
def __new__(self):
return object.__new__(self)
def __init__(self):
print 2


>>> X() # __init__ called twice, structure copied from number.py
2
2
<__main__.Y object at 0x7f287e7692d0>

如果我错了请纠正我。我不认为这个答案是完整的,但我发现这些并发症值得激励不要使用 __init__ 除了对象应该是不可变的之外,正如 Martijn Pieters 和 user4815162342 [source] 所提到的

等待 2 个反对票删除答案。

关于python - 为什么 sympy 覆盖 `__new__` 而不是 `__init__` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15929292/

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