Python for Java Programmers
Chapter 8: Object-oriented programming
Encapsulation
I have only talked about public attributes so far.
What about private attributes?
In Java, you are encouraged to hide all attributes with the private modifier, and to only expose these private attributes when needed using methods, or maybe using getter or setter methods, e.g. get_age() or set_age().
Python has a different philosophy when it comes to encapsulation. Python gives you a choice of either public or non-public attributes. In Python, technically you cannot make any attribute truly private (there are hacky ways to access it if a programmer is desperate), hence the term ‘non-public’ is used.
Quoting Python’s official PEP 8 style guide:
Public attributes are those that you expect unrelated clients of your class to use, with your commitment to avoid backwards incompatible changes. Non-public attributes are those that are not intended to be used by third parties; you make no guarantees that non-public attributes won’t change or even be removed.
So more than anything, it boils down to whether you think an attribute will never be changed in the future, and whether it really needs to be accessed as a public interface. If so, then definitely just make it public. Otherwise, you can choose to make it public or non-public.
There are several school of thoughts here even among Python developers. The official PEP 8 guide says “If in doubt, choose non-public; it’s easier to make it public later than to make a public attribute non-public.” But the more dominant view nowadays is to make everything public by default unless it is clearly non-public. If you ever need to make a public attribute non-public in the future, you can do this easily by exposing them as properties.