如何在Python中管理对可变属性的访问
在Python中,我们可以使用@property decorator来管理对属性的访问。例如,如果我们定义类:如何在Python中管理对可变属性的访问,python,properties,setter,mutable,Python,Properties,Setter,Mutable,在Python中,我们可以使用@property decorator来管理对属性的访问。例如,如果我们定义类: class C: def __init__(self,value): self._x = value @property def x(self): """I'm the 'x' property.""" return self._x 我们可以得到x的值,但不能改变它: c = C(1) #c.x = 4 #
class C:
def __init__(self,value):
self._x = value
@property
def x(self):
"""I'm the 'x' property."""
return self._x
我们可以得到x的值,但不能改变它:
c = C(1)
#c.x = 4 # <= this would raise an AttributeError: can't set attribute
c=c(1)
#c、 x=4#这样做的一种方法是返回属性的副本,而不是列表本身
>>> class C:
... def __init__(self, value):
... self._x = value
... @property
... def x(self):
... return self._x[:]
...
>>> c = C([1, 2, 3])
>>> c.x
[1, 2, 3]
>>> c.x.append(5)
>>> c.x
[1, 2, 3]
>>> c.x[0] = 6
>>> c.x
[1, 2, 3]
或者,该属性可以返回over属性或(例如dict.items()而不是dict)。如果属性较大,返回迭代器或视图可能有助于限制内存使用,并且与现代Python内置函数和类型的行为更加一致
如果可变属性本身包含可变属性(例如列表或字典列表),那么可能也需要返回这些对象的副本。如果对象图很深,这在时间和资源方面可能会很昂贵。有关自定义对象复制方式的方法,请参阅本模块的文档
这通常用于防止别名问题——其他对象包含对对象内部状态的引用
这确实意味着副本可能与真实属性不同步,但是,如果你的代码设计得很好,那么其他类无论如何都不应该保留你的类的值。将x
作为元组而不是列表?使用decorator@x.setter
创建另一个函数x
,而不是将元素设置为新值,在那里引发异常。@DEEPAKSURANA,具有decorator@x.setter
的函数不是由c.x[0]=1
调用的。
>>> class C:
... def __init__(self, value):
... self._x = value
... @property
... def x(self):
... return self._x[:]
...
>>> c = C([1, 2, 3])
>>> c.x
[1, 2, 3]
>>> c.x.append(5)
>>> c.x
[1, 2, 3]
>>> c.x[0] = 6
>>> c.x
[1, 2, 3]