What is Name Mangling in Python and How Does it Work With Detailed Examples

Learn a very important concept in Python called Name Mangling and how it works.

Picture of Nsikak Imoh, author of Macsika Blog
A blank image with the text What is Name Mangling in Python and How Does it Work With Detailed Examples
A blank image with the text What is Name Mangling in Python and How Does it Work With Detailed Examples

Table of Content

Python does not have an explicit access modifier, which means you cannot make a class attribute or method to be public/private.

However, class attributes or methods can be made private using a process called name mangling in Python.

In this article, you will learn a very important concept in Python called Name Mangling and how it works.

What is Name Mangling in Python?

Name mangling in Python is the process of an identifier with two leading underscores getting replaced with the class name followed by the identifier, e.g. _classname__identifier.

Where class name is the name of the current class.

It means that any identifier of the form __var_name — at least two leading underscores or at most one trailing underscore — is replaced with _classname__var_name.

What is the Use of Name Mangling in Python

Name mangling in Python is used to restrict private class attributes or methods from being accessed from outside the class.

Most high-level programming languages have a way of making the attributes and methods of the class to be private or protected.

Python does not have an access modifier, hence, you cannot restrict the class attributes and methods from getting access from outside the class.

To partially implement this, Python uses the concept of Name Mangling.

How to Use Name Mangling With Class Attributes in Python

Let's take a simple class example to show how name mangling works in Python:

class Car:
    def __init__(self):
        self.foo = 'Test One'
        self._bar = 'Test Two'
        self.__baz = 'Test Three'

car = Car()
Highlighted code sample.

Now, what do you think the values of foo, _bar, and __baz will be on instances of this Car class?

Let's take a look:

First attribute:

car.foo
Highlighted code sample.

Output

'Test One'
Highlighted code sample.

Second Attribute:

car._bar
Highlighted code sample.

Output

'Test Two'
Highlighted code sample.

Third Attribute:

car.__baz
Highlighted code sample.

Output

AttributeError: 'Car' object has no attribute '__baz'
Highlighted code sample.

Wait, why did we get that AttributeError when we tried to access the value of car.__baz?

This is python name mangling at work!

With Name mangling, it turns out this instance of the car class does not even have a __baz attribute.

Let's check the dir of the car object.

dir(car)
Highlighted code sample.

From the output below, you will notice the presence of the _bar and foo attribute in the list.

However, the __baz attribute is missing.

['_Car__baz', '__class__', '__delattr__',
 '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
 '__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
 '__subclasshook__', '__weakref__', '_bar', 'foo']
Highlighted code sample.

How to Access Name Mangled Attributes in Python

You can access name mangled attributes in python in two ways:

1. Accessing attributes via attribute name

One way to access an attribute with name mangling is through the name of the attribute as listed in the dir() list.

It follows the format:
_classname__attribute_name

Example of Accessing attributes via attribute name

class Car:
        def __init__(self):
            self.foo = 'Test One'
            self._bar = 'Test Two'
            self.__baz = 'Test Three'

car = Car()
Highlighted code sample.

To access the value of __baz, you can simply just call _Car__baz on the instance.

car._Car__baz
Highlighted code sample.

Output

'Test Three'
Highlighted code sample.

2. Accessing attributes via instance methods

Another way you can access the value of an attribute with name mangling is by creating a getter method and returning the value of the mangled attribute.

Example of Accessing attributes via instance methods

class Car:
    def __init__(self):
        self.foo = 'Test One'
        self._bar = 'Test Two'
        self.__baz = 'Test Three'
        
	def get_baz(self):
        return self.__baz

car = Car()
print(car.get_baz())
Highlighted code sample.

How to Use Name Mangling with Method Names in Python

Name mangling also applies to method names.

It affects all names that start with two underscore characters in a class context:

class Car:
    def __init__(self):
        self.foo = 'Test One'
        self._bar = 'Test Two'
        self.__baz = 'Test Three'
        
    def __drive(self):
        return "Zoom"

    def drive_car(self):
        return self.__drive()
        
car = Car()
Highlighted code sample.

If you call the __drive method in the class above on the instance, you will get

car.__drive()
Highlighted code sample.

Output

AttributeError: "'Car' object has no attribute '__drive'"
Highlighted code sample.

You can access it by calling the method through a non-mangled method or using the class and method name.

print(car._Car__drive())
print(car.drive_car())
Highlighted code sample.

Output

'Zoom'
Highlighted code sample.

Special Behavior in Name Mangling

Here's another unexpected example of name mangling in action.

It shows that name mangling isn't tied to class attributes specifically.

It applies to any name starting with two underscore characters used in a class context.

_Car__mileage = 23

class Car:
    def get_mileage(self):
        return __mileage

car = Car()
Highlighted code sample.

In the example above, we declared a global variable called _Car__mileage.

Then we accessed the variable inside the context of a class named Car.

Because of name mangling, we will be able to reference the _Car__mileage global variable as just __mileage inside the get_mileage() method on the class.

The Python interpreter automatically expands the name __mileage to _Car__mileage because it begins with two underscore characters.

Name mangling with method overriding

Using inheritance in object-oriented programming, you can override the base class method with a derived class method.

Supposing you want to write a method with the same name in the parent as well as in the child's class.

There is limited support in Python for a valid use case for class-private members to avoid name clashes with names defined by subclasses.

To avoid clashing when the parent class is inherited, you can add __ (double underscore) in front of the method name.

Both methods will be renamed through name mangling using the format below.

Name Mangling in the base class:

_<base_class_name>__<method_name>

Name Mangling in the derived class:

_<derived_class_name>__<method_name>

Let's look at this example and find out how this works.

Example of Name mangling with method overriding

# Base class
class Vehicle:
	def __init__(self):
		self.__info() # name mangling with the info method
	
	# default method for name mangling in the parent class
    def info(self):
        print('Print from Vehicle class')
    
    # private copy of original info() method for private class members
    __info = info # Name mangling with method overriding process

# Derived class
class Car(Vehicle):

	# provides a new signature for info() but
	# does not break __init__()
    def info(self):
        print('Print from Car class')

# Create an object of the Car class
car = Car()
car.info()
Highlighted code sample.

Output

Print from Vehicle class
Print from Car class
Highlighted code sample.

Wrap Off

We have learned about the introduction of the Name mangling process in this article.

We also learned how we can use the dir() method for name mangling in Python.

Then, we accessed the name mangled variables outside the class in which they are present.

Lastly, we also learned about how we can use name mangling process with method overriding in given subclasses in the program.

If you learned from this tutorial, or it helped you in any way, please consider sharing and subscribing to our newsletter.

Please share this post and for more insightful posts on business, technology, engineering, history, and marketing, subscribe to our newsletter.

Get the Complete Code of Python Code Snippets on Github.

Connect with me.

Need an engineer on your team to grease an idea, build a great product, grow a business or just sip tea and share a laugh?