Categories
identifier naming-conventions oop python

What is the meaning of single and double underscore before an object name?

1661

What do single and double leading underscores before an object’s name represent in Python?

2

1450

Single Underscore

In a class, names with a leading underscore indicate to other programmers that the attribute or method is intended to be be used inside that class. However, privacy is not enforced in any way.
Using leading underscores for functions in a module indicates it should not be imported from somewhere else.

From the PEP-8 style guide:

_single_leading_underscore: weak “internal use” indicator. E.g. from M import * does not import objects whose name starts with an underscore.

Double Underscore (Name Mangling)

From the Python docs:

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.

And a warning from the same page:

Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.

Example

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

11

  • 28

    What if there’s a variable name declared with 2 underscores which is not in the class? It’s just a normal variable then right?

    Jul 27, 2015 at 8:10


  • 152

    This answer is extremely misleading, as it leads the reader to believe that dunderscore is used to make instance attributes “superprivate”. This is not the case, as explained here by Raymond Hettinger, who explicitly states that dunderscore is incorrrectly used to mark members private, while it was designed to be the opposite of private.

    May 17, 2016 at 10:01


  • 24

    @MarkusMeskanen I disagree, the answer explicitly states the use of a dunderscore to make instances of class-private variables and methods. While the dunderscore was designed to make these methods and variables easily overwritten by subclasses (making them public), use of a dunderscore preserves a private instance for use within that class.

    – arewm

    Jul 5, 2016 at 15:11

  • 13

    @MarkusMeskanen: The freedom is for the subclasses to use the same names as the superclass does without clobbering the superclass — in otherwords, the superclasses’ dunder names become private to itself.

    Jul 15, 2016 at 17:48

  • 14

    For a single underscore, the answer says “nothing special is done with the name itself” but then goes on to say from M import * treats it differently…so something special is done…

    – flow2k

    May 11, 2018 at 17:27

446

  • _foo: Only a convention. A way for the programmer to indicate that the variable is private (whatever that means in Python).

  • __foo: This has real meaning. The interpreter replaces this name with _classname__foo as a way to ensure that the name will not overlap with a similar name in another class.

  • __foo__: Only a convention. A way for the Python system to use names that won’t conflict with user names.

No other form of underscores have meaning in the Python world. Also, there’s no difference between class, variable, global, etc in these conventions.

4

  • 7

    Just came across __foo and curious. How can it overlap with similar method names with other Classes? I mean you still have to access it like instance.__foo()(if it were not renamed by interpreter), right?

    May 9, 2013 at 8:03


  • 139

    This guy states that from module import * does not import underscore-prefixed objects. Therefore, _foo is more than just a convention.

    Jun 13, 2013 at 13:28

  • 6

    @Bibhas: if class B subclasses class A, and both implement foo(), then B.foo() overrides the .foo() inherited from A. An instance of B will only be able to access B.foo(), except via super(B).foo().

    – naught101

    Jan 26, 2015 at 3:11

  • 8

    For __dunder__ names, implicit invocations skip the instance dictionary, so it’s perhaps a little more than just a naming convention in some cases (see special method lookup section in datamodel).

    – wim

    Feb 20, 2020 at 20:43

365

Excellent answers so far but some tidbits are missing. A single leading underscore isn’t exactly just a convention: if you use from foobar import *, and module foobar does not define an __all__ list, the names imported from the module do not include those with a leading underscore. Let’s say it’s mostly a convention, since this case is a pretty obscure corner;-).

The leading-underscore convention is widely used not just for private names, but also for what C++ would call protected ones — for example, names of methods that are fully intended to be overridden by subclasses (even ones that have to be overridden since in the base class they raise NotImplementedError!-) are often single-leading-underscore names to indicate to code using instances of that class (or subclasses) that said methods are not meant to be called directly.

For example, to make a thread-safe queue with a different queueing discipline than FIFO, one imports Queue, subclasses Queue.Queue, and overrides such methods as _get and _put; “client code” never calls those (“hook”) methods, but rather the (“organizing”) public methods such as put and get (this is known as the Template Method design pattern — see e.g. here for an interesting presentation based on a video of a talk of mine on the subject, with the addition of synopses of the transcript).

Edit: The video links in the description of the talks are now broken. You can find the first two videos here and here.

10

  • 2

    So how do you decide whether to use _var_name or use var_name + excluding it from __all__?

    – endolith

    Jan 30, 2017 at 15:39


  • 3

    @endolith Use leading underscore to signal to the reader of your code that they probably shouldn’t use this (e.g., because you might change it in version 2.0, or even 1.1); use explicit __all__ whenever you want to make the module from spam import * friendly (including at the interactive interpreter). So most of the time, the answer is both.

    – abarnert

    Apr 25, 2018 at 17:15

  • @AlexMartelli Is this import related rule discussed legally somewhere in docs or elsewhere?

    – Vicrobot

    Aug 31, 2018 at 13:12

  • 1

    I like the C++ analogy. Firstly, I dislike it when people call the _ private. Evidently I’m talking about analogies, since nothing’s truly private in Python. When diving into semantics I’d say we can tie the _ to Java’s protected since proctected in Java means “derived classes and/or within same package”. Replace package with module since PEP8 already tells us that _ is not just a convention when talking about * imports and there you have it. And definitely __ would be equivalent to Java’s private when talking about identifiers within a class.

    Jun 4, 2019 at 19:03

  • 3

    While a decent answer, it’s also heavily self promotional.

    Jan 7, 2020 at 7:42