Chapter 8: Object-oriented programming

Encapsulation

face Josiah Wang

I have only talked about public attributes so far.

What about private attributes?

In C++, attributes are private by default. You are encouraged to hide all attributes, and to only expose these private attributes 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.