2013-04-10 15 views
6

Jedes Objekt in sympy ist eine Unterklasse der Basic Klasse, und sie alle verwenden __new__ ohne __init__, und meistens ist es so etwas wieWarum überschreibt sympy "__new__" statt "__init__"?

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

Was ist der Unterschied __init__ zu verwenden wie

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

?

+2

Ich denke, dass sie alle unveränderlich sein sollen? –

+0

@MartijnPieters - Ich glaube, dass sie hashbar sein müssen, um eine erneute Arbeit zu vermeiden, die bereits erledigt wurde a.la memoization. – mgilson

+0

Es könnte nur ein historischer Unfall sein; ältere Versionen (z. B. 0.5.x) haben eine wesentlich komplexere Struktur, in der sie möglicherweise gerechtfertigt waren. – ecatmur

Antwort

2

Werfen Sie einen Blick auf Number. Sie wollen, dass die Klasse des Objekts flexibel ist. Number(...) => Int/Float/... was nicht erreicht werden kann durch __init__.

Außerdem die __init__ würde die Argumente __new__ bekommen, aber Sie nicht die ursprünglichen Argumente müssen, finden Sie matexpr.py oder Sie müssen sie angepasst werden, was __new__ bereits tat (zum Beispiel for __reduce__).

Die meisten Objekte definieren ihre eigenen __slots__, also gibt es feste Attribute, die ihnen zugewiesen werden können. Die Zuordnung kann in __new__ und __init__ erfolgen. Ich sehe nicht die Notwendigkeit, eine neue __init__ zu öffnen, nur um sie zu setzen und keine anderen Operationen - Wie Martijn Pieters und user4815162342 [source] wies darauf hin, die Objekte sind unveränderlich.

Manchmal __init__ nicht genannt wird, ein- oder zweimal, wenn Sie die Klasse ändern:

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> 

mich korrigieren, wenn ich falsch bin. Ich glaube nicht, diese Antwort abgeschlossen ist, aber diese sind Komplikationen ich wert motivierend fand nicht __init__ zusätzlich zu verwenden, dass die Objekte unveränderlich sein sollte, wie von Martijn Pieters erwähnt und user4815162342 [source]

Warten auf 2 downvotes die Antwort zu löschen.

+1

+1 - deine vorherigen Antworten waren ein bisschen ... kryptisch ... aber das hier ergibt Sinn –

Verwandte Themen