Classes and Objects
Private and Protected Members
Python doesn’t have true private members in the same way as some other languages (like Java or C++). Instead, it uses a naming convention to indicate that an attribute or method should be treated as private or protected.
Name Mangling: Python uses name mangling to achieve a form of privacy. If you prefix an attribute or method name with double underscores (__
), it undergoes name mangling. This makes it harder (but not impossible) to access it from outside the class.
class MyClass:
def __init__(self, value):
self.__private_var = value # Name mangled
def get_private(self):
return self.__private_var
my_instance = MyClass(10)
print(my_instance.get_private()) # Access through a getter method.
#print(my_instance.__private_var) # This will raise an AttributeError (most likely)
print(my_instance._MyClass__private_var) # Access through name mangling (avoid this!)
The mangled name _MyClass__private_var
is created by adding _ClassName
before the original name. While this can be accessed, it’s generally considered bad practice to directly access mangled names.
Protected Members: The convention for protected members is a single underscore prefix (_
). This signals to other programmers that the attribute or method is intended for internal use within the class and its subclasses, but it’s not truly protected. It can still be accessed from outside the class, but doing so is discouraged.
class MyClass:
def __init__(self, value):
self._protected_var = value
def get_protected(self):
return self._protected_var
my_instance = MyClass(20)
print(my_instance.get_protected()) # Access directly; no error
print(my_instance._protected_var) # Access directly; no error
Best Practices:
- Use
__
(double underscore) for attributes/methods you want to prevent accidental access from outside the class. Provide getter/setter methods for controlled access. - Use
_
(single underscore) to signal that an attribute/method is intended for internal use within the class and its subclasses. Remember that it’s not truly protected, only a convention. - Avoid directly accessing mangled names (
_ClassName__attributeName
).