Python OOP Access Modifiers: Public, Protected, and Private
Learn about Python's access modifiers used in object-oriented programming to control access to class members. Understand the distinctions between public, protected, and private members, and how they affect access within and outside the class.
Python - Access Modifiers
The Python access modifiers are used to restrict access to class members (i.e., variables and methods) from outside the class. There are three types of access modifiers: public, protected, and private.
- Public members − A class member is said to be public if it can be accessed from anywhere in the program.
- Protected members − They are accessible from within the class as well as by classes derived from that class.
- Private members − They can be accessed from within the class only.
Usually, methods are defined as public and instance variables are private. This arrangement ensures the principle of encapsulation.
Access Modifiers in Python
Unlike C++ and Java, Python does not use the Public, Protected, and Private keywords to specify the type of access modifiers. By default, all the variables and methods in a Python class are public.
Example
class Employee:
'Common base class for all employees'
def __init__(self, name="Bhavana", age=24):
self.name = name
self.age = age
e1 = Employee()
e2 = Employee("Bharat", 25)
print("Name: {}".format(e1.name))
print("Age: {}".format(e1.age))
print("Name: {}".format(e2.name))
print("Age: {}".format(e2.age))
Output
Name: Bhavana
Age: 24
Name: Bharat
Age: 25
Python doesn't enforce restrictions on accessing any instance variable or method. However, Python prescribes a convention of prefixing the name of a variable/method with a single or double underscore to emulate the behavior of protected and private access modifiers.
- To indicate that an instance variable is private, prefix it with a double underscore (e.g.,
__age
). - To imply that a certain instance variable is protected, prefix it with a single underscore (e.g.,
_salary
).
Another Example
class Employee:
def __init__(self, name, age, salary):
self.name = name # public variable
self.__age = age # private variable
self._salary = salary # protected variable
def displayEmployee(self):
print("Name : ", self.name, ", age: ", self.__age, ", salary: ", self._salary)
e1 = Employee("Bhavana", 24, 10000)
print(e1.name)
print(e1._salary)
print(e1.__age)
Output
Bhavana
10000
Traceback (most recent call last):
File "example.py", line 14, in
print(e1.__age)
^^^^^^^^
AttributeError: 'Employee' object has no attribute '__age'
Python displays an AttributeError because __age
is private and not available for use outside the class.
Name Mangling
Python doesn't block access to private data; it just leaves it up to the programmer's wisdom not to write any code that accesses it from outside the class. You can still access the private members by Python's name mangling technique.
Name mangling is the process of changing the name of a member with a double underscore to the form object._class__variable
. If required, it can still be accessed from outside the class, but this practice should be refrained from.
In our example, the private instance variable __age
can be accessed as e1._Employee__age
.
Modified Print Statement
print(e1._Employee__age)
Output
24
Python Property Object
Python's standard library has a built-in property()
function. It returns a property object and acts as an interface to the instance variables of a Python class.
Syntax
property(fget=None, fset=None, fdel=None, doc=None)
The property()
function uses getter, setter, and delete methods defined in a class to define a property object for the class.
Getters and Setter Methods
A getter method retrieves the value of an instance variable, usually named as get_varname
, whereas the setter method assigns value to an instance variable, named as set_varname
.
Example
class Employee:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def set_name(self, name):
self.__name = name
def set_age(self, age):
self.__age = age
e1 = Employee("Bhavana", 24)
print("Name:", e1.get_name(), "age:", e1.get_age())
e1.set_name("Archana")
e1.set_age(21)
print("Name:", e1.get_name(), "age:", e1.get_age())
Output
Name: Bhavana age: 24
Name: Archana age: 21
The getter and setter methods can retrieve or assign values to instance variables. The property()
function uses them to add property objects as class attributes.
Defining Property
class Employee:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def set_name(self, name):
self.__name = name
def set_age(self, age):
self.__age = age
name = property(get_name, set_name, "name")
age = property(get_age, set_age, "age")
e1 = Employee("Bhavana", 24)
print("Name:", e1.name, "age:", e1.age)
e1.name = "Archana"
e1.age = 23
print("Name:", e1.name, "age:", e1.age)
Output
Name: Bhavana age: 24
Name: Archana age: 23