Single vs Double Leading Underscore in Python
In Python, the difference between a single leading underscore
(_var) and double leading underscores (__var)
comes down to convention versus interpreter-level enforcement. A single
leading underscore serves as a stylistic hint to developers that a
variable or method is intended for internal use, while double leading
underscores invoke name mangling, where the Python interpreter
dynamically rewrites the attribute name to prevent naming collisions in
inheritance hierarchies.
Single Leading Underscore
(_variable)
A single underscore before a name is a standard PEP 8 naming convention indicating that an attribute, function, or method is intended to be private or internal to its containing module or class.
- No Access Restriction: Python does not enforce
privacy. You can still access and modify a single-underscored attribute
directly from outside the class (e.g.,
obj._internal_method()). - Wildcard Import Behavior: When using wildcard
imports (
from module import *), names starting with a single underscore are automatically excluded from the import, unless specifically listed in the module’s__all__list. - Primary Purpose: Communicating intent to other developers that the implementation details may change and should not be relied upon as a public API.
Double Leading Underscore
(__variable)
Double leading underscores trigger name mangling. Name mangling is a syntactic feature enforced by the Python interpreter to help prevent subclasses from accidentally overriding parent class attributes and methods.
- Name Mangling Mechanism: When an attribute name
begins with at least two underscores and at most one trailing
underscore, the interpreter rewrites the identifier by prefixing it with
an underscore and the enclosing class name:
_ClassName__attribute. - Access Behavior: Accessing
obj.__attributedirectly from outside the class raises anAttributeError. However, this is not true data hiding; the attribute can still be accessed using its mangled name (e.g.,obj._MyClass__attribute). - Primary Purpose: Avoiding namespace collisions between parent classes and subclasses, particularly in large codebases or libraries where classes are designed to be extended by third parties.
Summary of Differences
- Enforcement: The single underscore is strictly a convention followed by developers, whereas double underscores invoke specific compiler and runtime behavior (name mangling).
- Scope of Effect: Single underscores affect module
imports via
import *, while double underscores affect attribute resolution on class instances. - Usage Context: Use a single underscore to signal "private" or internal implementation details. Use double underscores sparingly, strictly when you need to avoid attribute name conflicts in deep inheritance structures.