Why does sympy override `__new__` instead of` __init__`?

Each object in sympy is a subclass of the Basic class, and they all use __new__ without __init__ , and basically it's something like

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

What is the difference between using __init__ as

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

?

+6
source share
1 answer

Take a look at Number . They want the class of the object to be flexible. Number(...) => Int/Float/... , which cannot be achieved using __init__ .

In addition, __init__ will receive __new__ arguments, but you do not need the original arguments, see matexpr.py or you need them to be adapted to what __new__ already did (for example for __reduce__ ).

Most objects define their own __slots__ , so fixed attributes can be assigned to them. Assignment can be done in __new__ and __init__ . I do not see the need to open a new __init__ , simply installing them and not performing any other operations. As Martijn Pieters and user4815162342 [source] indicated objects immutable.

Sometimes __init__ is called more than once or twice if you change the class:

 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> 

Correct me if I am wrong. I do not think this answer is complete, but it is a difficulty that I thought it advisable not to use __init__ , except that the objects should be immutable, as mentioned by Martijn Pieters and user4815162342 [source]

Waiting for 2 downvotes to delete the response.

+2
source

All Articles