为什么sympy会覆盖`__new__`而不是`__init__`?

时间:2013-04-10 14:52:57

标签: python

sympy中的每个对象都是Basic类的子类,它们都使用__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

1 个答案:

答案 0 :(得分:2)

看看Number。他们希望对象的类是灵活的。 Number(...) => Int/Float/...无法实现的__init__

此外,__init__会获得__new__的参数,但您不需要原始参数,请参阅matexpr.py或者您需要将它们调整为已__new__的内容做了(例如for __reduce__)。

大多数对象定义自己的__slots__,因此可以为其分配固定属性。可以在__new____init__中完成作业。我没有看到需要打开一个新的__init__来设置它们而不进行其他操作 - 正如Martijn Pieters和user4815162342 [source]所指出的那样,对象是不可变的。

如果您更改班级,有时会调用__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删除答案。