为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Python中管理对可变属性的访问

如何在Python中管理对可变属性的访问

慕丝7291255 2021-04-06 15:38:35
在Python中,我们可以使用@property装饰器来管理对属性的访问。例如,如果我们定义类: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([0,0])c.x[0] = 1 # <= this works有办法预防吗?如果x是一个列表,我只想使用类C的方法来更改x的位置值。
查看完整描述

1 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

一种方法是返回属性的副本,而不是列表本身。


>>> 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内置函数和类型的行为更加一致。


如果可变属性本身包含可变属性(例如,列表或字典的列表),则可能也有必要返回这些对象的副本。如果对象图很深,则在时间和资源上可能会很昂贵。有关自定义对象复制方式的方法,请参阅复制模块的文档。


此技术通常用于防止别名问题-其他对象持有对您对象内部状态的引用。


这确实意味着副本可能与real属性不同步,但是如果您的代码设计良好,则其他类无论如何都不应保留您的类的值。


查看完整回答
反对 回复 2021-04-20
  • 1 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信