How to manage access to a mutable attribute in Python

痞子三分冷 提交于 2021-01-20 08:19:01

问题


In Python, we can use the @property decorator to manage access to attributes. For example, if we define the class:

class C:
    def __init__(self,value):
        self._x = value

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

we can get the value of x, but not change it:

c = C(1)
#c.x = 4  # <= this would raise an AttributeError: can't set attribute

However, if the attribute is of a mutable type (e.g., a list), we can set a different value for a position of the attribute:

c = C([0,0])
c.x[0] = 1 # <= this works

Is there a way to prevent it? If x is a list, I would like to able to change the value of positions of x only using methods of class C.


回答1:


One way to do this would be to return a copy of the attribute, rather than the list itself.

>>> 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]

Alternatively, the property could return an iterator over attribute, or a view (for example dict.items() instead of a dict). Returning iterators or views may help limit memory use if the attribute is large, and is more consistent with the behaviour of modern Python builtin functions and types.

If the mutable attribute contains mutable attributes itself - for example a list of lists or dictionaries - then it may be necessary to return copies these objects too. This can be expensive in terms of time and resources if the object graph is deep. See the docs for the copy module for ways to customise how objects are copied.

This technique is commonly used to prevent the problem of aliasing - where other objects hold references to your object's internal state.

It does mean that the copies may go out of sync with the real attribute, but if your code is well designed then other classes should not be holding onto the values of your class anyway.



来源:https://stackoverflow.com/questions/51114984/how-to-manage-access-to-a-mutable-attribute-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!