I started learning programming in Python and was never exposed to the concept of public/private for a while. After learning about the concept with Java I still didn't see too much use for it and was always fond of Python's "we're all consenting adults" principle. Especially when the usual get/set methods add so many lines of code to otherwise one-liners. Eventually after programming substantial projects in C++ I started to understand its benefits such as allowing encapsulating implementation details. It also clearly expresses when a variable should not be set directly as its setting should have side effects.
When my Python programs became large enough I often forget whether an attribute is only used internally and do not know whether the attribute is safe to change. Often I end up changing the attribute, running the program, encountering an exception, fixing the error in dependent code, and repeating. In Python we can use the leading underscore pseduo-private convention and the property function to gain these advantages while still allowing code to access what it wants.
As an example here is a point class. The attributes 'x' and 'y' should really not be allowed to be set directly because the 'distance' attribute needs to be recomputed any time (this may also be a sufficiently complicated expression that recomputing each time would take too long).
class Point:
def __init__(self, x, y):
self._x = x
self._y = y
self._distance = (x**2 + y**2) ** (1/2)
@property
def x(self):
return self._x
@property
def y(self):
return self._x
@property
def distance(self):
return self._distance
If your attributes are read-only the code can be quite concise.
class Point:
x = property(lambda self: self._x)
y = property(lambda self: self._y)
distance = property(lambda self: self._distance)
def __init__(self, x, y):
self._x = x
self._y = y
self._distance = (x**2 + y**2) ** (1/2)
I've really taken to the later style but haven't really used it extensively. Is there any disadvantages of making most "public" attributes properties? I can only think of:
- Readability? Personally the latter style is even more readable to me as any attributes you care about when not implementing the class are clear and up top.
- Not clear to other developers? When using this in solo projects it's not a problem. But this clearly follows the rules of Python and should be easily understandable.
- Less efficient? It's another layer of indirection so that's a possibility, however attribute access is not usually a very limiting case.
- Not as quick to write/setup? This style doesn't have to be followed exactly for every class and possible addition, but can be added when a solid implementation really starts to take form.
- Less Pythonic? Possibly, but I feel like the criteria for Pythonic should not be arbitrary and have to do with readability and efficient.