我正在尝试创建一个新的不可变类型,类似于内置的Fraction
,但不是从它派生而来。 Fraction类是这样创建的:创建Fraction类:
# We're immutable, so use __new__ not __init__
def __new__(cls, numerator=0, denominator=None):
...
self = super(Fraction, cls).__new__(cls)
self._numerator = ...
self._denominator = ...
return self
但我不明白这与其他有何不同。
def __init__(self, numerator=0, denominator=None):
...
self._numerator = ...
self._denominator = ...
使用相同值创建2个(实际上评论中指出这不是常见情况)Fraction
对象不会创建指向同一对象/内存位置的2个标签
尽管源代码中有注释,但它们实际上并不是不可变的:
f1 = Fraction(5)
f2 = Fraction(5)
id(f1), id(f2)
Out[35]: (276745136, 276745616)
f1._numerator = 6
f1
Out[41]: Fraction(6, 1)
f2
Out[42]: Fraction(5, 1)
id(f1)
Out[59]: 276745136
那么这种方式的目的是什么?
文档中提到:
__new__()主要用于允许不可变类型(例如int、str或tuple)的子类自定义实例创建。它也通常在自定义元类中被覆盖,以便自定义类创建。
所以,如果我不是子类化内置类型,但我正在从头开始创建一个不可变类型(继承自object),我是否仍然需要使用它?
int(1000)
而不是int(5)
进行上述测试,则会发现i1 is i2
为false。 - John Kugelman