If you are familiar with any other programming languages like Java or C++ you must have come across the terms private attributes and public attributes. They are usually also known as the Access modifiers. In languages like C++ and java, there are keywords used to restrict and make the member public or private.
✏️ Access Modifiers are used to restrict or control the accessibility of class resources by declaring them as public, private, and protected.
But, there are no keywords known as public, private, and protected in Python. Hence, we have to use certain conventions to restrict the members.
Without further ado, let’s just dive in to learn more about the modifiers.
📚 Public Attribute In Python
- In Python, every member of the class is public by default.
- Public members in a class can be accessed from anywhere outside the class.
- You can access the public members by creating the object of the class.
class Music: # Creating a constructor def __init__(self): self.genre = "Pop" self.singer = "Coldplay" # These are public attributes # Creating a function def foo(self): song = 'Hymn For The Weekend' return song # Creating object of the class m = Music() # Accessing the members inside the class print("Song: ", m.foo()) print("Genre:", m.genre) print("Singer:", m.singer)
Song: Hymn For The Weekend Genre: Pop Singer: Coldplay
📝Note: Even derived class can access the public members.
📚 Private Attributes in Python
Unfortunately, Python does not have a way to effectively restrict access to instance variables or methods. 😟
However, we do have a workaround. To declare a member as private in Python, you have to use double underscore
__ as a prefix to the variables. Private members are restricted within the same class, i.e. we can access the private members only within the same class.
class Music: # constructor def __init__(self): # These are private variables self.__genre = "Pop" self.__singer = "Coldplay" # private function def __func(self): print('Music: Hym For The Weekend') def foo(self): # Accessing private members of the class obj.__func() print("Genre:", obj.__genre) print("Singer:", obj.__singer) obj = Music() # Creating an object of the Music class obj.foo() # calling the private function
Music: Hym For The Weekend Genre: Pop Singer: Coldplay
In the above example, we have used two underscores before the identifiers
self.__singer) to make the variables private. Similarly, the same convention was used for the function
func which ensured that it is a private method.
If you try to access the private member outside the class, you will get an AttributeError.
class Music: # constructor def __init__(self): # These are private variables self.__genre = "Pop" self.__singer = "Coldplay" # private function def __func(self): print('Music: Hym For The Weekend') def foo(self): # Accessing private members of the class print("Genre:", obj.__genre) print("Singer:", obj.__singer) # Creating object of the class obj = Music() # Trying to access the private attributes from outside the class obj.__func() print("Genre:", obj.__genre) print("Singer:", obj.__singer)
Traceback (most recent call last): File "main.py", line 24, in <module> obj.__func() AttributeError: 'Music' object has no attribute '__func'
So, this brings us to the question – How to access the private attributes from outside the class? Is there a way?🤔
When you use a double underscore (e.g.,
__var), Python plays around with the name giving it properties of a private attribute. However, the variable can still be accessed from outside the class using its obfuscated name. Hence, it is not strictly private.
This brings us to a very important concept in Python – Name Mangling. You can access the private attributes outside the class using name mangling.
✨ Name Mangling in Python
Name Mangling is a process in Python, where, if a method has, in any event, two underscores before the name, and at the most one underscore following the name, it gets replaced with
_ClassName before it, for instance,
_ClassName__ method(). Since the name is changed internally by the interpreter, so we cannot access the variable utilizing its original name and that is how you can hide data in Python.
Note: Name Mangling is essentially used to avoid overriding the methods for parent classes by inherited classes.
Let’s look at an example to understand how private variables are accessed outside the class with the help of name mangling:
# Defining a class class Music: # Creating a constructor def __init__(self): # These are private attributes self.__genre = "Pop" self.__singer = "Coldplay" # This is a public attribute self.releaseyear = 2000 # Creating a function def foo(self): print("Song: Trouble") # Creating object of the class obj = Music() # Calling the method inside the class obj.foo() # Accessing the private members outside the class using name mangling print("Genre:", obj._Music__genre) print("Singer:", obj._Music__singer) # Accessing the public member normally print("Year of release:", obj.releaseyear)
Song: Trouble Genre: Pop Singer: Coldplay Year of release: 2000
📚 Protected Attributes in Python
You can access protected attributes of a class from within the class, and they can also be accessed by the sub-classes. This facilitates inheritance in Python.
To make a variable protected, you have to add a single underscore (e.g.
_x) as a prefix to it. To make it truly protected, you also have to use a property decorator.
# Defining a class class Music: def __init__(self): self._song = 'Trouble' @property def foo(self): return self._song @foo.setter def foo(self, new_song): # overloading foo self._song = new_song obj = Music() print('Song - ', obj.foo) obj.foo = 'Hym For The Weekend' print('New Song - ', obj.foo)
Song - Trouble New Song - Hym For The Weekend
@propertydecorator ensured that
foo()method is a property.
@foo.setterdecorator allowed us to overload the
foo()method. Now, the variable
songis protected. But this
🚨 Alert! – You can still access song from outside using
obj._song. Thus you should always avoid accessing or modifying variables prefixed by
_ from outside the class.
Thus, we learned about one of the most important OOP concepts in Python in this tutorial, i.e., how you can use public, private and protected attributes in Python.
👨🎓 SHUBHAM SAYON
👩🎓 RASHI AGARWAL