为什么在Python中扩展不可变类时需要使用__new __()?

时间:2015-06-21 18:10:46

标签: python

我正在阅读掌握面向对象的Python 这本书。在本书讨论__new__方法和不可变对象的部分中,它说__new__()方法用于扩展__init__()方法可以使用的不可变类。很容易被覆盖。它还给出了一个例子如下

class Float_Fail(float):
    def __init__(self, value, unit):
        super().__init__(value)
        self.unit = unit

f = Float_Fail(6.5, "knots")

TypeError Traceback (most recent call last)
<ipython-input-2-9511e6ca03be> in <module>()
----> 1 f = Float_Fail(6.5, "knots")
TypeError: float() takes at most 1 argument (2 given)

我只是好奇为什么float会出现这个错误。我的意思是,我们可以像这样初始化一个浮点数:

f = float(1.1)

这并不意味着__init__()类的float方法将数字作为它的第二个参数。如果没有,如何在Python中实现不可变类的初始化?

2 个答案:

答案 0 :(得分:3)

如果您执行MyClass(1),则1确实作为参数传递给__init__。但__new__之前会调用__init__,因此1 首先作为参数传递给__new__。您看到的错误是因为您没有覆盖__new__,因此正在调用继承的float.__new__,并且它不接受您的额外参数。它甚至没有机会尝试调用__init__,因为它在尝试调用__new__时失败。

the documentation中对此进行了解释。正如那里明确指出的那样,你在课堂上传递的论据(例如1中的MyClass(1))会传递给 __new__ 和< / em> __init__,按此顺序。

答案 1 :(得分:0)

__init__方法运行时,该对象已存在。由于对象是不可变的,因此无法在__init__中更改其值。