2013-04-10 14 views
6

Każdy obiekt w sympy jest podklasą klasy Basic, a wszystkie one używać __new__ bez __init__, a przede wszystkim jest to coś jakDlaczego sympy zastępuje `__new__` zamiast` __init__`?

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

Jaka jest różnica użyciem __init__ jak

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

?

+2

Chyba wszystkie mają być niezmienne? –

+0

@MartijnPieters - Sądzę, że muszą być dostępne, aby uniknąć ponownego wykonywania pracy, która została już wykonana. – mgilson

+0

To może być tylko historyczny wypadek; starsze wersje (na przykład 0.5.x) mają znacznie bardziej złożoną strukturę, gdzie być może było to uzasadnione. – ecatmur

Odpowiedz

2

Spójrz na Number. Chcą, aby klasa obiektu była elastyczna. Number(...) => Int/Float/..., którego nie można uzyskać przez __init__.

Ponadto __init__ dostanie argumenty __new__ ale nie trzeba oryginalne argumenty, zobacz matexpr.py czy trzeba im być dostosowane do tego, co już zrobił __new__ (np for __reduce__).

Większość obiektów definiuje swoje własne __slots__, więc istnieją ustalone atrybuty, które można do nich przypisać. Przypisanie można wykonać w __new__ i __init__. Nie widzę potrzeby otwierania nowego __init__ tylko po to, aby je ustawić i nie wykonywać żadnych innych operacji - jako Martijn Pieters i użytkownik 4815162342 [source] wskazali, że obiekty są niezmienne.

Czasami __init__ nazywa nie, raz lub dwa razy, jeśli zmienić klasę:

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> 

Popraw mnie jeśli się mylę. Nie sądzę, że ta odpowiedź jest kompletna, ale są to powikłania znalazłem warto motywować, aby nie używać __init__ dodatkowo, że obiekty powinny być niezmienne jak wspomniano przez Martijn Pieters i user4815162342 [source]

Oczekiwanie na 2 downvotes usunąć odpowiedź.

+1

+1 - twoje poprzednie odpowiedzi były trochę ... tajemnicze ... ale ten ma sens –

Powiązane problemy