对于旨在用作不可变类的类,例如:
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
然而,这并不是真正必要的。你的类的文档应该清楚地表明它的实例是不可变的,所以任何使用你的类的人都应该知道,如果他们想在多个地方引用它,他们可以安全地重用一个实例,就像他们对内置的一样。在不可变类型中,例如 int
、str
、tuple
和 frozenset
。例如,
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/