In Python, double underscores (`__`) are used in various contexts to indicate special methods or attributes, private variables, and more. Understanding their use is essential for writing clean and effective Python code. Here’s a detailed explanation of different scenarios where double underscores are used:
1. Dunder Methods
Double underscores are often used for special methods, commonly known as “dunder” methods (short for “double underscore”). These methods have a specific meaning and are used to define the behavior of objects. Examples include:
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"MyClass with value {self.value}"
def __repr__(self):
return f"MyClass({self.value!r})"
def __add__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value + other.value)
return NotImplemented
In this example:
__init__
is the constructor method that initializes the object.__str__
returns a human-readable string representation of the object.__repr__
returns an unambiguous string representation of the object, often used for debugging.__add__
defines the behavior of the addition operator (`+`) for instances of the class.
2. Name Mangling
Double underscores are also used for name mangling, which is a way to make attributes private by prefixing them with double underscores. This prevents name clashes in subclasses:
class MyClass:
def __init__(self, value):
self.__value = value
def get_value(self):
return self.__value
obj = MyClass(10)
print(obj.get_value()) # Output: 10
print(obj.__value) # AttributeError: 'MyClass' object has no attribute '__value'
In this example, __value
is name-mangled to _MyClass__value
. It is not directly accessible from outside the class, making it effectively private.
3. Double Underscores in Method Names
Methods with double underscores at both the beginning and end of their names are considered special methods and are used to hook into Python’s internal behavior:
class MyClass:
def __eq__(self, other):
return isinstance(other, MyClass) and self.value == other.value
def __len__(self):
return len(str(self.value))
In this example:
__eq__
allows comparison using the equality operator (`==`).__len__
allows the use of the built-in `len()` function on instances of the class.
4. Double Underscores for Method Resolution Order (MRO)
Python uses double underscores in the method resolution order and the `__mro__` attribute to determine the order in which base classes are searched for a method:
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
print(D.__mro__) # Output: (, , , , )
5. Double Underscores in Python Modules
Double underscores can also be used in module names to indicate special modules, such as:
__main__
– The name of the top-level script being executed.__init__.py
– A module used to initialize a Python package.
6. Common Pitfalls
Be cautious with name mangling and special methods:
- Double underscore prefixes are meant to be used to avoid name clashes, not for strict encapsulation.
- Overusing or misusing special methods can lead to code that is difficult to understand or maintain.
Double underscores in Python serve various important roles from defining object behavior to managing name collisions and module initialization. Understanding these uses will help you write more effective and idiomatic Python code.