Photo By Clément H On Unsplash

Private, “Protected” Attributes in Python — Demystified Once and For All

All there is to know about private and “protected” attributes in 748 words

Never, ever use two leading underscores. This is annoyingly private. — Ian Bicking, Creator of pip, virtualenv, and many others

How many times have you encountered these words: Public, Private, and Protected in the world of Python? And how many times those one leading underscores _, two leading underscores __puzzled you, trying to make sense of them?

Well, let’s demystify them once and for all. What’s the use of private and “protected” attributes. And, how they look like in the Python world.

What’s The Point of A Private Attribute Anyway?

Consider this scenario: You have a class named Vehiclewhich internally uses an instance attribute named horn and does not want to expose it. Now, you want to subclass Vehicleand name your own class MyCar.

If you create your own horn instance attribute inside the class MyCaryou will be overriding the Vehicle’s horn instance attribute. What happens as a consequence is that you will smash all those methods in Vehicle class that are using the horn attribute. Worse yet, it would be a headache to debug the problems that ensue.

To prevent such scenarios, the developer of Vehicle class would make the horn attribute private to prevent such inadvertent accidents.

Private Attributes in Python

In the world of Python, unlike Java, there’s no way of creating a private modifier. What python gives you is a simple mechanism to prevent accidental overriding of an attribute in your class if someone wants to inherit from your class.

In the previous example, if you wanted to make the horn attribute private, you would need to prefix it with two underscores: __horn.This way, Python will store this attribute name in the instance __dict__ prefixed with an underscore and the class name. Thus, in the Vehicle class, your __horn attribute becomes _vehicle__horn and in MyCar class it becomes _MyCar__horn.This feature of python goes by the delicate name of name mangling. Here’s the code for what we discussed so far:

Example 01 — Private attributes where the names are mangled

The important note here is that name mangling is all about safety and not security. It will not keep you protected against intentional wrongdoing; just, accidental overriding. In the example above, you can easily alter the value of a private attribute simply by doing this: v1._vehicle__horn = 'new value'.

“Protected” Attributes in Python

Neither name mangling feature, nor the skewed appearance of the names written as self.__horn is loved by the Pythonistas. In public repositories, you’ll notice that developers often prefer to follow the convention of adding just one leading underscore (self._horn) to “protect” them from inadvertent modification.

Critics suggest that to prevent attribute clobbering it’s enough to simply stick to the convention of prepending the attribute with a single underscore. Here’s the full quote from Ian Bicking I cited at the beginning of the article;

Never, ever use two leading underscores. This is annoyingly private. If name clashes are a concern, use explicit name mangling instead (e.g., _MyThing_balabla). This is essentially the same thing as double-underscore, only it’s transparent where double underscore obscures.

I must note that an attribute with a single leading underscore _ does not mean anything special to the python interpreter. But, it’s one of those strong conventions in the world of Pythonistas. If you see one, it means that you should not access such attributes from outside the class. You can even observe that even in some corners of the official Python documentation, attributes with a single leading underscore _ are called “protected.”

Even though the practice of “protecting” an attribute using a single leading underscore is common, it is not as often to hear them being called “protected” attributes. Some even call them “private.”

In Sum

The main point of making an attribute private is to prevent the accidental overriding of that attribute by the subclasses. The official way to make a variable private in python is by adding two underscore e.g.self.__privateattr.But, in the python community, there’s a strong preference to just add a single leading underscore when making a variable private. You may often hear or see that such attributes are called “protected.”

So, just know that making a variable private in python is about safety and it’s enough to protect them from inadvertent overriding by adding a single leading underscore: e.g. self._protected.

If you enjoyed my article and want to read more, consider signing up to become a Medium member. It’s $5 a month, giving you unlimited access to stories on Medium. By using the following link, you would also support me as a writer.

--

--

Productivity is My Passion | Programmer | I Read Obsessively, Experiment Like a Maniac, And Write What Actually Works in Here.