Способ инкапсуляции полей экземпляра в Python - PullRequest
2 голосов
/ 16 марта 2011

Является ли это использование @ property decorator подходящим для получения хорошей инкапсуляции полей экземпляра? Я пытаюсь добиться того, чтобы клиенты класса Foobar не могли каким-либо образом назначать произвольные значения полю vel экземпляров Foobar, фактически игнорируя правила назначения, определенные в методе установки свойств.

Спасибо.

class Foobar(object):
    def __init__(self):
        self._vel = 0

    @property
    def vel(self):
        return self._vel

    @vel.setter
    def vel(self, v):
        self._vel = v if v > 0 else 0

Поле выглядит хорошо инкапсулированным.

>>> foobar = Foobar()
>>> foobar.vel
0
>>> foobar.vel = -1
>>> foobar.vel
0
>>> foobar.vel = 1
>>> foobar.vel
1

1 Ответ

4 голосов
/ 16 марта 2011

Вы не можете запретить пользователю обходить что-либо в python. Всегда есть способ monkeypatch / отражать / проверять атрибуты; Там нет поддержки песочницы объекта.

В вашем примере:

>>> foobar._vel = -1

Обходит свойство полностью и присваивается непосредственно реальному атрибуту. Вы не можете предотвратить это вообще. Есть способы сделать это сложнее, но пользователь может назначить, если он действительно хочет, так какой смысл?

Обычный подход, похоже, заключается в том, чтобы полагаться на тот факт, что пользователи вашей библиотеки взрослые и доверяют им:

Объявите диапазон ожидаемых значений в документации и попросите пользователей следовать. Если они этого не делают, это их вина.

...