Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info>: > The convention is, if the caller messes with your private attributes > or variables, and their code breaks, they have nobody to blame but > themselves, and we are allowed to laugh at them. We're consenting > adults here.
I would take it further: as a rule, user code should not think of modifying the contents of an object unless it is clearly documented as a supported operation. IOW, you should consider all attributes private, or at least read-only. BTW, the principle is actually enforced for some objects: >>> "hello".join = lambda *x: "world" Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'str' object attribute 'join' is read-only >>> "hello".joinn = lambda *x: "world" Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'str' object has no attribute 'joinn' >>> "hello".__setattr__ = lambda *x: None Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'str' object attribute '__setattr__' is read-only A tougher issue is with encapsulation. A derived class might accidentally step on the toes of the base class by redefining an attribute: ======================================================================== class Base: def __init__(self): self._secret = 17 def divulge_secret(self): return self._secret class Derived(Base): def __init__(self): self._secret = 1 print(Derived().divulge_secret()) ======================================================================== which outputs 1. Marko -- https://mail.python.org/mailman/listinfo/python-list