2013-04-10 53 views
6

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 

+2

我猜他們都應該是不可變的? – 2013-04-10 14:54:19

+0

@MartijnPieters - 我認爲它們需要可以被排除以避免重做已經完成的工作。 – mgilson 2013-04-10 14:56:18

+0

這可能只是一個歷史事故;較舊的版本(例如0.5.x)具有明顯更復雜的結構,可能是合理的。 – ecatmur 2013-04-10 17:26:11

回答

2

看一看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

+1 - 你以前的答案有點......神祕......但這個有意義 – 2013-04-11 10:05:42

相關問題