2 回答
TA贡献1873条经验 获得超9个赞
归根结底,您无法保护您的对象免受检查和操纵。另外,总是问自己“究竟来自谁?” 当您想“保护”数据时。
有时,围绕不阅读文档的用户编写代码是不值得的。
话虽如此,你可以考虑return tuple(self.__x)
在吸气剂中。另一方面,如果__x
包含其他可变对象,则不会阻止用户操作这些内部对象。(return list(self.__x)
也将返回数据的浅拷贝,但隐含的“嘿,我应该是不可变的!”信号。)
您绝对应该考虑的是在方法中更改self.__x = xx
为,以便用户执行self.__x = list(xx)
__init__
var = [] c = C(var)
不能“轻松”(或错误地,同样,可能存在可变的内部对象)c
通过 mutating改变 的状态var
。
TA贡献1851条经验 获得超3个赞
最简单的方法是接受一个可迭代对象__init__并在内部将其转换为元组:
class C(object):
def __init__(self, iterable):
self._tuple = tuple(iterable)
@property
def x(self):
return self._tuple
@x.setter
def x(self, value):
raise RuntimeError('can\'t reset the x attribute.')
c = C([1, 2, 3])
# c.x = 'a' Will raise 'RuntimeError: can't reset the x attribute.'
print(c.x)
像这样的设计使从类实例化的任何对象都是不可变的,因此变异操作应该返回新对象而不是更改当前对象的状态。
例如,假设您要实现一个函数,该函数使 中的每个项目递增 1 self.x。使用这种方法,您需要编写类似于以下内容的内容:
def increment_by_one(c):
return C(t+1 for t in c.x)
由于创建和销毁对象会产生相关成本x,因此应根据您的用例评估此方法(防止属性突变)与 @timgeb 建议的方法之间的权衡。
添加回答
举报