β Introduction
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.
Example 1:
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)
Output:
Song: Hymn For The Weekend Genre: Pop Singer: Coldplay
?Note: Even derived class can access the public members.
Example 2:
? 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.
Example:
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
Output:
Music: Hym For The Weekend Genre: Pop Singer: Coldplay
Explanation:
In the above example, we have used two underscores before the identifiers (self.__genre
and 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.
β οΈ CAUTION
If you try to access the private member outside the class, you will get an AttributeError.
Example:
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)
Output:
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, __method()
becomes _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)
Output:
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.
Example:
# 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)
Output:
Song - Trouble New Song - Hym For The Weekend
Explanation:
@property
decorator ensured thatfoo()
method is a property.@foo.setter
decorator allowed us to overload thefoo()
method. Now, the variablesong
is 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.
β Conclusion
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.
I hope this article helped you. Please stay tuned and subscribe for more interesting discussions in the future.
Authors:
?β? SHUBHAM SAYON
?β? RASHI AGARWAL