"Private" attribute properties in Python
Solution 1:
If you want to discourage users from changing a property, but want it to be clear that they can read it, I'd use @property
without providing a setter, similar to what you described earlier:
class Data(object):
def __init__(self):
self._x = []
self._y = []
@property
def x(self):
return self._x
@property
def y(self):
return self._x
I know you mention "What if I wanted to add a setter to the property?", but I guess I would counter that with: Why add the setter if you don't want your clients to be able to set the property? Internally, you can access self._x
directly.
As for a client directly accessing _x
or _y
, any variable with an '_' prefix is understood to be "private" in Python, so you should trust your clients to obey that. If they don't obey that, and end up screwing things up, that's their own fault. This kind of mindset is counter to a many other languages (C++, Java, etc.) where keeping data private is considered very important, but Python's culture is just different in this regard.
Edit
One other note, since your private properties in this particular case are lists, which are mutable (unlike strings or ints, which are immutable), a client could end up changing them somewhat accidentally:
>>> d = Data()
>>> print d.x
['1', '2']
>>> l = d.x
>>> print l
['1', '2']
>>> l.append("3")
>>> print d.x
['1', '2', '3'] # Oops!
If you want to avoid this, you'd need your property to return a copy of the list:
@property
def x(self):
return list(self._x)