Один из способов сделать это - вернуть копию атрибута, а не сам список.
>>> 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]
В качестве альтернативы, свойство может возвращать атрибут iterator over или view (например, dict.items () вместо dict). Возвращение итераторов или представлений может помочь ограничить использование памяти, если атрибут большой и более соответствует поведению современных встроенных функций и типов Python.
Если атрибут mutable содержит сами изменяемые атрибуты - например, список списков или словарей, - возможно, потребуется также вернуть копии этих объектов. Это может быть дорого с точки зрения времени и ресурсов, если граф объекта является глубоким. См. Документы для модуля copy , чтобы узнать, как настроить копирование объектов.
Этот метод обычно используется для предотвращения проблемы алиасинга - когда другие объекты содержат ссылки на внутреннее состояние вашего объекта.
Это означает, что копии могут не синхронизироваться с реальным атрибутом, но если ваш код хорошо спроектирован, тогда другие классы не должны все равно удерживать значения вашего класса.