Skip to content

Access Modifiers in Python: Public, Private, and Protected Members

Updated: at 05:12 AM

In object-oriented programming languages like Python, access modifiers or access specifiers are used to restrict access to class members such as attributes and methods. By controlling access, they prevent misuse or unintentional modification of a class’ internal representation.

Python handles access modifiers differently than languages like Java or C++. It has no explicit syntax for declaring a member private or protected. However, Python conventions and naming practices designate whether a member should be considered public, private or protected.

This guide will cover the following topics in using access modifiers in Python:

Table of Contents

Open Table of Contents

Public Members in Python

Public members in Python are attributes or methods that are freely accessible and modifiable by any part of the program. They serve as the external interface of a class.

In Python, any member not designated as private or protected is public by default. No special syntax is required to declare a public member:

class Person:

  def __init__(self, name):
    self.name = name

  def say_hello(self):
    print("Hello, my name is", self.name)

p = Person("John")
p.name = "Mary" # Modifying public attribute
p.say_hello()

The name attribute and say_hello() method are public and can be freely accessed and modified by any external code.

Advantages of public members:

Disadvantages of public members:

So public members are suitable when you want attributes and methods to be open for modification and use throughout the program. Access control should be implemented with private and protected members.

Private Members in Python

Private members limit access to class members from outside the class. This allows control over the internal representation and prevents accidental modification.

Python does not have a built-in private keyword like some OOP languages. Instead, it utilizes naming conventions to designate private members.

Any identifier prefixed with two underscores (__) is treated as private:

class Person:

  def __init__(self, name):
    self.__name = name # Private attribute

  def __private_method(self):
    print(self.__name)

Trying to access __name or __private_method() from outside the class will fail:

p = Person("John")
print(p.__name) # AttributeError
p.__private_method() # AttributeError

This enforces privacy by making it harder to inadvertently access the identifiers from another part of the program.

Name Mangling

However, Python does not completely block access to such variables. Instead, it uses name mangling to modify the identifier name to include the class name.

So the actual mangled name for a private member would be _ClassName__identifier:

class Person:

  def __init__(self, name):
    self.__name = name

  def get_name(self):
    return self.__name

p = Person("John")
print(p._Person__name) # Accessing mangled __name

The motivation behind this name mangling is to prevent accidental clashes between identifier names used in a subclass. So you can reuse a private identifier name in the subclass without modifying the superclass private member.

While name mangling allows access to private members, it should be avoided. It breaks encapsulation and harder to keep track of mangled names. Private members are meant for use only within the class definition.

Advantages of private members:

Disadvantages of private members:

So private members provide some access control for class internals. But they are not rigorously enforced in Python compared to languages like Java.

Protected Members in Python

Protected members allow access to class members within the class and its subclasses only. This provides selective access control between the class and its child classes.

In Python, protected members follow the naming convention of a single leading underscore _:

class Person:

  def __init__(self, name):
    self._name = name # Protected attribute

  def _protected_method(self):
    print(self._name)

class Student(Person):

  def get_name(self):
    return self._name

So _name and _protected_method() can be accessed within Person and Student. But code outside these classes will get an attribute error if trying to access them.

Protected provides a middle ground between public and private access.

Advantages of protected members:

Disadvantages of protected members:

Protected members enable class extension and inheritance while limiting wider access. But they are also subject to potential misuse.

Access Modifiers Usage Considerations

Here are some key points to consider when deciding between public, private and protected members in Python:

Overall, apply access modifiers judiciously based on your specific program requirements and constraints. Do not assume they provide absolute access restriction.

Example Use Cases

Here are some examples of appropriate use cases for the different access modifiers:

Public

Private

Protected

Best Practices

Below are some best practices to use access modifiers effectively in Python:

Pros and Cons of Access Modifiers in Python

Pros

Cons

Overall, Python access modifiers serve their purpose in most cases but have caveats compared to other OOP languages. Following conventions and best practices will provide reasonable access control for the public API, private internals, and protected subclass extensions of a Python class.