python - 不可变类和 __copy__

标签 python

对于旨在用作不可变类的类,例如:

class Immutable:
    def __init__(self, field):
        self._field = field
    def field(self):
        return self._field

__copy__ 中返回 self 可以吗?

    def __copy__(self):
        return self

最佳答案

如果您的目标是让您的类的用户可以安全地对其实例调用 copy.copy,那么请务必添加一个 __copy__方法:

def __copy__(self): 
    return self

然而,这并不是真正必要的。你的类的文档应该清楚地表明它的实例是不可变的,所以任何使用你的类的人都应该知道,如果他们想在多个地方引用它,他们可以安全地重用一个实例,就像他们对内置的一样。在不可变类型中,例如 intstrtuplefrozenset。例如,

a, b, c = Immutable(123), Immutable(456), 42
d = {'one': a, 'two': b, 'three': c}

如果您不提供 __copy__ 方法,而某人 确实 在一个实例上调用了 copy.copy,那么他们将得到一个作为原始实例的克隆的新对象。使用如上定义的 __copy__,他们当然只会获得对原始对象的引用。

顺便说一句,您应该将 .field (和任何其他属性)变成 property ,并且不要提供 setter。

class Immutable:
    def __init__(self, field):
        self._field = field

    @property
    def field(self):
        return self._field

现在您可以像调用简单属性一样调用字段方法:

a = Immutable(123) 
print(a.field)

当然,您仍然可以按正常方式改变 ._field 属性,但是使用您的类的任何人都应该知道他们不应该这样做。 :)


在问题评论中,我们讨论了这样一个事实,即在元组上调用 copy.copy 会返回对原始元组的引用,即使 tuple 没有定义 __复制__。没有一个内置类型定义 __copy__,但请记住它们都是用 C 语言定义的,因此它们的工作方式与用 Python 定义的类略有不同。 FWIW,在任何内置不可变类型上调用 copy.copy 返回对原始对象的引用,并在任何内置可变类型上调用 copy.copy类型返回一个克隆。

关于python - 不可变类和 __copy__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42137653/

相关文章:

Python 修补 __new__ 方法

python - MySQL :"Access denied to x@localhost' 使用 python

python - 根据多种条件格式化 Pandas 数据框中单元格的颜色

python - TensorFlow 代码帮助 - 入门示例

c++ - 使用高度图扭曲图像?

帮助中列出的 Python 模块与 pip 找到的不同

python - 我如何检查字典中的循环/后边? {...}

python - Flask-sqlalchemy : sqlalchemy. exc.InvalidRequestError

python - 在 Python 中共享存储在更高目录中的模块和类的最佳实践

python tkinter在函数之间传递变量