Properties in Python.

Python does not have the concept of public and private members. How can you protect your class attributes?

The short answer is: You cannot protect attributes from being accessed from the outside the class. Not by prefixing them with one underscore (_), and also not by prefixing them with two underscores (__).

In the following example an Employee object is instantiated. Then a new value is assigned to the salary attribute:

class Employee:
    def __init__(self):
        self.salary = 0

e = Employee()
e.salary = 2000
print(e.salary)

Output:

2000

Prefixing with underscores

Prefixing with one underscore does not make the attribute private as you can see in the following example:

class Employee:
    def __init__(self):
        self._salary = 0

e = Employee()
e._salary = 2000
print(e._salary)

Output:

2000

The only thing we have gained here is that the attribute is prefixed with an underscore which might trigger the user to think that the attribute should not be used from the outside.

By prefixing salary with two underscores, name mangling will be applied. It will obfuscate the attribute name to make it harder to access but this technique does not make attributes private and name mangling is also not meant to do that.

Property decorator

We now know that prefixing an attribute with a single underscore shows the intent of the attribute being private. Now you can use the property decorator to encapsulate the attribute.

class Employee:
    def __init__(self):
        self._salary = 0

    @property
    def salary(self):
        return self._salary

    @salary.setter
    def salary(self, value):
        print(f"I can check here if value {value} is valid")
        self._salary = value

e = Employee()
e.salary = 2000
print(e.salary)

Output:

I can check here if value 2000 is valid
2000
      

Notice that technically you could still set e._salary = 824356467526. I repeat, the use of properties and prefixed attributes do not make members private. Underscores will not change the visibility of attributes in Python.

That said, if users of the class only access unprefixed attributes, you have a bit more control over the values of the attributes. Consider the technique to be 'Encapsulation Light'.