Understand single and double underscores in Python names

Use underscore conventions deliberately, understand class name mangling, and distinguish internal attributes from special methods and pattern wildcards.

Best practices
Python programming and application logging

A leading single underscore, _name, signals an internal implementation detail by convention. A name such as __name inside a class definition can trigger name mangling to reduce accidental clashes with subclasses. Neither is an access-control boundary.

Mark an internal attribute

class Service:
    def __init__(self):
        self._cache = {}

service = Service()
print(service._cache)  # Accessible, but intended as an implementation detail

Callers can access _cache, but doing so couples them to an internal detail that may change. At module level, names beginning with _ are omitted by default from from module import *; an explicit __all__ can change what is exported.

Avoid accidental subclass name collisions

class Base:
    def __init__(self):
        self.__state = "base"

class Child(Base):
    def __init__(self):
        super().__init__()
        self.__state = "child"

obj = Child()
print(obj._Base__state)   # base
print(obj._Child__state)  # child

Within a class definition, identifiers beginning with at least two underscores and not ending with two or more are mangled using the class name. In ordinary cases, __state becomes _ClassName__state. Leading underscores in the class name are stripped when forming that prefix.

Outside the class, obj.__state does not automatically become either of those attributes and normally raises AttributeError. A literal string passed to getattr(obj, "__state") is not automatically rewritten either. Name mangling is a lexical naming mechanism, not hidden storage.

Recognize other forms

Form Meaning
_name Conventionally internal
__name inside a class Eligible for name mangling
__name__ A special-name form reserved for Python protocols
_ in ordinary assignments or loops An ordinary name often used for an ignored value
_ in a match pattern A wildcard that does not bind a name

The interactive interpreter commonly uses _ for the last displayed result; application code and tools may assign it another meaning.

FAQ

Does mangling make an attribute private? No. The mangled name is still accessible. It protects against accidental collisions rather than intentional access.

Should I invent a special method such as foo? Avoid it. That naming space is reserved for language-defined protocols and can conflict with future behavior.

Can a subclass still modify the base attribute? Yes, by intentionally accessing the mangled base name. Its own __state spelling normally creates a separate attribute instead.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting