为什么sympy覆盖`__new__`而不是`__init__`?
在sympy
每个对象是Basic类的子类,并且它们都使用__new__
没有__init__
,而且大多是像为什么sympy覆盖`__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和用户指出的那样,对象是不可变的。
有时__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个downvotes删除答案的对象应该是一成不变的。
+1 - 你以前的答案有点......神秘......但这个有意义 – 2013-04-11 10:05:42
我猜他们都应该是不可变的? – 2013-04-10 14:54:19
@MartijnPieters - 我认为它们需要可以被排除以避免重做已经完成的工作。 – mgilson 2013-04-10 14:56:18
这可能只是一个历史事故;较旧的版本(例如0.5.x)具有明显更复杂的结构,可能是合理的。 – ecatmur 2013-04-10 17:26:11