2013-04-10 15 views
6

Ogni oggetto in sympy è una sottoclasse della classe Basic, e tutti usano __new__ senza __init__, e per lo più si tratta di qualcosa di simile aPerché sympy sovrascrive `__new__` invece di` __init__`?

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

Qual è la differenza di utilizzare __init__ come

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

?

+2

Suppongo che tutti dovrebbero essere immutabili? –

+0

@MartijnPieters - Credo che debbano essere lavabili per evitare di rifare il lavoro che è già stato fatto a.la memoizzazione. – mgilson

+0

Potrebbe essere solo un incidente storico; le versioni precedenti (ad esempio 0.5.x) hanno una struttura significativamente più complessa in cui forse era giustificata. – ecatmur

risposta

2

Dai un'occhiata allo Number. Vogliono che la classe dell'oggetto sia flessibile. Number(...) => Int/Float/... che non può essere raggiunto da __init__.

Inoltre il __init__ otterrebbe gli argomenti di __new__ ma non ti servono gli argomenti originali, vedere matexpr.py o avete bisogno loro di essere adattati per quanto __new__ già fatto (per esempio for __reduce__).

La maggior parte degli oggetti definisce il proprio __slots__ in modo che ci siano attributi fissi che possono essere assegnati a loro. L'assegnazione può essere effettuata in __new__ e __init__. Non vedo la necessità di aprire un nuovo __init__ per impostarli e non fare altre operazioni - Come Martijn Pieters e user4815162342 [source] hanno sottolineato che gli oggetti sono immutabili.

volte __init__ si chiama non, una o due volte se si cambia la classe:

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> 

correggetemi se sbaglio. Non credo che questa risposta è completa ma queste sono le complicazioni che ho trovato la pena di motivare a non utilizzare __init__ in aggiunta a che gli oggetti devono essere immutabili come detto da Martijn Pieters e user4815162342 [source]

In attesa di 2 downvotes per eliminare la risposta.

+1

+1 - le tue risposte precedenti erano un po '... criptiche ... ma questo ha senso –

Problemi correlati