Advanced Lesson 2
Advanced Object-Oriented Programming
Chapter 3: Encapsulation
Non-public attributes
As an example, let’s say we have the class definition for VainPerson
with the attribute name
.
class VainPerson:
def __init__(self, name):
self.name = name
lovely_person = VainPerson("Beauty")
print(lovely_person.name) # Beauty
lovely_person.name = "Average"
print(lovely_person.name) # Average
VainPerson
definitely does not like people assigning it random names. It also does not like people knowing its real name! No, that should be kept secret! 🤐🤐🤐
You can make an attribute non-public by adding a double underscore before its name.
class VainPerson:
def __init__(self, name):
self.__name = name
lovely_person = VainPerson("Beauty")
print(lovely_person.__name) # AttributeError: 'VainPerson' object has no attribute '__name'
If you try this out, you will see that __name
cannot be accessed directly anywhere else other than inside VainPerson
class. Python has performed what is known as name mangling to hide this variable from public view. There is a way to access it if you are really desperate (it’s via lovely_person._VainPerson__name
), but you really should not be doing this! 👎
If you have previously come across OOP, you might have also noticed that I used the word non-public rather than the more conventional term “private”. This is because no variables are really private in Python (even __name
can be accessed as mentioned)! Python’s philosophy is to be ‘open’.
If you try to set lovely_person.__name = "A new name"
, it does work. BUT it actually refers to a new attribute __name
and not the one you defined in the class (that one has been automatically renamed to _VainPerson__name
).