Private attributes in Python are defined with a double underscore prefix (__attribute
) to limit direct access from outside the class.
Key takeaways:
Access modifiers control access to a class’s variables and methods.
Access modifiers come in three varieties: private, protected, and public.
Public members are accessible from any part of the program.
The class and its derived classes can access protected members.
Private members are only accessible within the class that defines them.
The use of access modifiers contributes to better maintainability and code encapsulation.
Object-oriented programming languages (OOP) are powerful tools that allow programmers to model real-world entities and their interactions. OOP helps organize and structure code into reusable components for improved modularity by combining data and actions into objects. It aids in managing complexity by breaking down problems into smaller units, improving code reusability through inheritance and polymorphism, and enhancing maintainability and extensibility through encapsulation. Additionally, OOP implements data abstraction to protect data integrity.
A fundamental principle in OOP is data encapsulation, which focuses on controlling access to the internal components of a class. By encapsulating data, the class hides its internal state and only exposes necessary interfaces for interaction. This principle helps maintain data integrity by ensuring that data can only be accessed or modified in controlled ways.
Most OOP languages like C++ and Java use access modifiers to control access to class members (variables and methods). These modifiers typically include:
Public access modifiers: Accessible from anywhere.
Protected access modifiers: Accessible within the class and by subclasses.
Private access modifiers: Accessible only within the class.
Python does not have built-in access modifiers like C++ or Java. All class variables and methods are public by default. However, Python follows a convention to imitate access control by prefixing variable/method names with underscores.
In Python, we can control the perceived accessibility of variables and methods by adding underscores to their names:
Single underscore (_): Indicates that a variable or method is intended for internal use and should not be accessed directly.
Double underscore (__): Changes the variable name to make accessing from outside the class harder but not impossible.
This convention helps maintain the principles of data encapsulation in Python despite the absence of formal access modifiers.
Access Modifier | Naming Convention | Purpose |
Public | No underscores | Accessible from anywhere (inside or outside the class). |
Protected | Single underscore (_) | Intended for internal use within the class and its subclasses. Access outside is discouraged. |
Private | Double underscore (__) | Meant for internal use only within the class. |
By default, all members (instance variables and methods) are public. This means that all variables and methods declared inside the class can be accessed by the class itself or anywhere outside of that specific class. Let’s see an example below:
class Person:def __init__(self, name, age):self.name = name # publicself.age = age # public
The above class has two different member variables (name
and age
). These variables can be accessed directly from an instance of the Person
class. This is demonstrated below:
class Person:def __init__(self, name, age):self.name = name # public attributeself.age = age # public attributedef display_info(self):print(f"Name: {self.name}, Age: {self.age}")# Create an object of Personperson = Person("Educative", 21)# Accessing public attributesprint("Name:", person.name) # Direct access allowedprint("Age:", person.age) # Direct access allowedperson.display_info() # Access through method
To protect an instance variable or method, the convention is to prefix the name with a single underscore _
. This is demonstrated below:
class Person:def __init__(self, name, age):self._name = name # protectedself._age = age # protected
The member variables for the Person
class in the code shown above have the prepended underscore (_
). This means that the member variables can only be accessed within the class they’re defined in and in the subclasses of the parent class.
Note: An important thing to note here is that when the variable is accessed without the underscore (
_
) within the same class, the interpreter will not check for access modifiers because accessibility inside the same class is allowed.
class Person:def __init__(self, name, age):self.name = name # public attributeself._age = age # protected attribute (convention)def display_info(self):print(f"Name: {self.name}, Age: {self._age}")# Create an object of Personperson = Person("Educative", 21)# Accessing protected attributes (allowed but discouraged)print("Name:", person.name) # Direct access allowed (public)print("Age:", person._age) # Direct access allowed but discouraged (protected)person.display_info() # Access through method# Example with subclass accessing protected attributeclass Student(Person):def display_student_info(self):print(f"Student Name: {self.name}, Age: {self._age}")student = Student("Educative", 21)student.display_student_info() # Accessing protected attribute within subclass
We can make an instance variable or method private by using the double underscore __
, as shown below:
class Person:def __init__(self, name, age):self.__name = name # privateself.__age = age # private
Making a class’s member variables private can only be used inside the class. The __age
instance variables cannot be accessed outside the class; doing so will give an AttributeError
.
class Person:def __init__(self, name, age):self.name = name # public attributeself.__age = age # private attribute (name mangling)def display_info(self):print(f"Name: {self.name}, Age: {self.__age}")# Create an object of Personperson = Person("Educative", 21)# Accessing public attribute (allowed)print("Name:", person.name)# Attempting to access private attribute will raise an AttributeErrortry:print("Age:", person.__age) # This will raise an AttributeErrorexcept AttributeError as e:print(f"Error: {e}")person.display_info() # Access through method# Accessing private attribute via name mangling (not recommended)print("Age (via name mangling):", person._Person__age) # Accessing the private attribute using name mangling
Note: You can still access the private members outside the class. Python performs name mangling, so every member prefixed with
__
is changed to_class__member
.
To demonstrate each access modifier, we create a Person
class with three members: name
(public), _age
(protected), and __height
(private). Next, we make an instance of Person
and try accessing its members:
class Person:def __init__(self, name, age, height):self.name = name # publicself._age = age # protectedself.__height = height # privatep1 = Person("John", 20, 170)print(p1.name) # public: can be accessedprint(p1._age) # protected: can be accessed but not advised# print(p1.__height) # private: will give AttributeError
Try running the code with the last line uncommented
print(p1.__height)
. You will notice it gives anAttributeError
since you cannot access a private class member outside the class.
Learn the basics with our engaging Learn Python course!
Start your coding journey with Learn Python, the perfect course for beginners! Whether exploring coding as a hobby or building a foundation for a tech career, this course is your gateway to mastering Python—the most beginner-friendly and in-demand programming language. With simple explanations, interactive exercises, and real-world examples, you’ll confidently write your first programs and understand Python essentials. Our step-by-step approach ensures you grasp core concepts while having fun. Join now and start your Python journey today—no prior experience is required!
Haven’t found what you were looking for? Contact Us
Free Resources