python - "We' 是不可变的,所以使用 __new__ 而不是 __init__"

标签 python constructor immutability

我在模块 fraction.py 中找到了这个短语标准库:

class Fraction(numbers.Rational):
    ...

    # We're immutable, so use __new__ not __init__
    def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
        """Constructs a Rational.
        ...

我对此感到困惑,因为严格来说,Fraction 实例不是不可变的:

import fractions

fraction = fractions.Fraction(3, 2)
fraction._numerator = 1  # it works
print(fraction)  # 1/2

因此,我要求更多说明为什么使用 __new__ 而不是 __init__ 以及这个短语在这里的含义。

最佳答案

它在逻辑上是不可变的,而不是强制的。在 Python 中真正实现不变性基本上是不可能的。更疯狂的执法尝试总是会遇到更疯狂的绕行。例如,分子分母 是没有 setter 的属性,其中存在一些“强制”,但您已经找到了绕过它的方法。

如果你真的想搞砸 Fraction 对象,你可以,而且你可以做比设置 _numerator 更糟糕的事情,但你是在自找问题。

关于python - "We' 是不可变的,所以使用 __new__ 而不是 __init__",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57741347/

相关文章:

python - 合并两个字符串列表

python - XML : remove child node of a node

c++ - 我们可以根据引用参数类型重载构造函数吗?

java - 为什么标记为 final 的对象可以在 Java 中被修改并调用非 final 方法?

c# - 这种强制不变性的模式有什么缺点?

python - 如何获取 Udp 缓冲区大小超过丢失的数据包

qt - QPluginLoader.instance() - 它是如何工作的?

java - 从 Java 构造函数获取变量

scala - Scala Streams 中如何实现不变性?

python - 创建相应的字母数字元素列表