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

Asked 2023-09-21 08:11:07 View 366,523

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

Answers

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!'}

Answered   2023-09-21 08:11:07

  • 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? - anyone
  • 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. - anyone
  • @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. - anyone
  • @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. - anyone
  • 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... - anyone
  • _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.

Answered   2023-09-21 08:11:07

  • 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? - anyone
  • This guy states that from module import * does not import underscore-prefixed objects. Therefore, _foo is more than just a convention. - anyone
  • @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(). - anyone
  • 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). - anyone

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.

Answered   2023-09-21 08:11:07

  • So how do you decide whether to use _var_name or use var_name + excluding it from __all__? - anyone
  • @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. - anyone
  • @AlexMartelli Is this import related rule discussed legally somewhere in docs or elsewhere? - anyone
  • 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. - anyone
  • While a decent answer, it's also heavily self promotional. - anyone

._variable is semiprivate and meant just for convention

.__variable is often incorrectly considered superprivate, while it's actual meaning is just to namemangle to prevent accidental access[1]

.__variable__ is typically reserved for builtin methods or variables

You can still access .__mangled variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something like instance._className__mangled

Example:

class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

>>> t = Test()
>>> t._b
'b'

t._b is accessible because it is only hidden by convention

>>> t.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'

t.__a isn't found because it no longer exists due to namemangling

>>> t._Test__a
'a'

By accessing instance._className__variable instead of just the double underscore name, you can access the hidden value

Answered   2023-09-21 08:11:07

  • but how about if "__a" was a class variable, then you cannot access it even with the instructions from python docs.. - anyone
  • Please can you update your answer with an example of double underscore with respect to inheritence? - anyone
  • ._variable, according to the posts above and PEP-8, is not only a convention: "from M import * does not import objects whose names start with an underscore.". However, in the presented case showing it as a class attribute, it doesn't change anything. - anyone
  • .__variable is often incorrectly considered superprivate this is somewhat misleading. The double underscores, whiles does name mangle, does so in an attempt to make it properly private. - anyone

Single underscore at the beginning:

Python doesn't have real private methods. Instead, one underscore at the start of a method or attribute name means you shouldn't access this method, because it's not part of the API.

class BaseForm(StrAndUnicode):
    
    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

    errors = property(_get_errors)

(This code snippet was taken from Django source code: django/forms/forms.py). In this code, errors is a public property, but the method this property calls, _get_errors, is "private", so you shouldn't access it.

Two underscores at the beginning:

This causes a lot of confusion. It should not be used to create a private method. It should be used to avoid your method being overridden by a subclass or accessed accidentally. Let's see an example:

class A(object):
    def __test(self):
        print "I'm a test method in class A"

    def test(self):
        self.__test()
 
a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!

Output:

$ python test.py
I'm test method in class A
I'm test method in class A

Now create a subclass B and do customization for __test method

class B(A):
    def __test(self):
        print "I'm test method in class B"

b = B()
b.test()

The output will be...

$ python test.py
I'm test method in class A

As we have seen, B.test() didn't call B.__test() methods, as we might expect. But in fact, this is the correct behavior for __. The two methods called __test() are automatically renamed (mangled) to _A__test() and _B__test(), so they do not accidentally override. When you create a method starting with __ it means that you don't want anyone to be able to override it, and you only intend to access it from inside its own class.

Two underscores at the beginning and at the end:

When we see a method like __this__, don't call it. This is a method which Python is meant to call, not you. Let's take a look:

>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11

>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60

There is always an operator or native function which calls these magic methods. Sometimes it's just a hook Python calls in specific situations. For example __init__() is called when the object is created after __new__() is called to build the instance...

Let's take an example...

class FalseCalculator(object):

    def __init__(self, number):
        self.number = number

    def __add__(self, number):
        return self.number - number

    def __sub__(self, number):
        return self.number + number

number = FalseCalculator(20)
print number + 10      # 10
print number - 20      # 40

For more details, see the PEP-8 guide. For more magic methods, see this PDF.

Answered   2023-09-21 08:11:07

According to Meaning of Underscores in Python

  • Single Leading Underscore(_var): Naming convention indicating a name is meant for internal use. Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.
  • Single Trailing Underscore(var_): Used by convention to avoid naming conflicts with Python keywords.
  • Double Leading Underscore(__var): Triggers name mangling when used in a class context. Enforced by the Python interpreter.
  • Double Leading and Trailing Underscore(__var__): Indicates special methods defined by the Python language. Avoid this naming scheme for your own attributes.
  • Single Underscore(_): Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.

Answered   2023-09-21 08:11:07

Sometimes you have what appears to be a tuple with a leading underscore as in

def foo(bar):
    return _('my_' + bar)

In this case, what's going on is that _() is an alias for a localization function that operates on text to put it into the proper language, etc. based on the locale. For example, Sphinx does this, and you'll find among the imports

from sphinx.locale import l_, _

and in sphinx.locale, _() is assigned as an alias of some localization function.

Answered   2023-09-21 08:11:07

  • Yes this answer is helpful ; the gettext module describes this pattern "gettext works by looking up literal strings in a database of translations, and pulling out the appropriate translated string. The usual pattern is to bind the appropriate lookup function to the name “_” (a single underscore character) so that the code is not cluttered with a lot of calls to functions with longer names." Maybe that's what sphinx is doing "under the hood"; soemthing like the examplet = gettext.translation('example_domain', 'locale', fallback=True); _ = t.gettext - anyone
  • I could not find the import or creation of the _ localization function in my project. I realized my project uses gettext.install(...), which "installs the function _() in Python’s builtins namespace...", a technique of the "class-based API" of the gettext module (vs using the API directly gettext.gettext(...)). More on built-ins vs a module's global namespace here - anyone

Since so many people are referring to Raymond's talk, I'll just make it a little easier by writing down what he said:

The intention of the double underscores was not about privacy. The intention was to use it exactly like this

class Circle(object):

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        p = self.__perimeter()
        r = p / math.pi / 2.0
        return math.pi * r ** 2.0

    def perimeter(self):
        return 2.0 * math.pi * self.radius

    __perimeter = perimeter  # local reference


class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

It's actually the opposite of privacy, it's all about freedom. It makes your subclasses free to override any one method without breaking the others.

Say you don't keep a local reference of perimeter in Circle. Now, a derived class Tire overrides the implementation of perimeter, without touching area. When you call Tire(5).area(), in theory it should still be using Circle.perimeter for computation, but in reality it's using Tire.perimeter, which is not the intended behavior. That's why we need a local reference in Circle.

But why __perimeter instead of _perimeter? Because _perimeter still gives derived class the chance to override:

class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

    _perimeter = perimeter

Double underscores has name mangling, so there's a very little chance that the local reference in parent class get override in derived class. thus "makes your subclasses free to override any one method without breaking the others".

If your class won't be inherited, or method overriding does not break anything, then you simply don't need __double_leading_underscore.

Answered   2023-09-21 08:11:07

  • Thank you, the slide did not display properly so i ended up not untersanting why my code would fail. - anyone
  • Hmm, I got the same answer whether perimeter had leading dunder or not. - anyone
  • _var: variables with a leading single underscore in python are classic variables, intended to inform others using your code that this variable should be reserved for internal use. They differ on one point from classic variables: they are not imported when doing a wildcard import of an object/module where they are defined (exceptions when defining the __all__ variable). Eg:

    # foo.py
    
    var = "var"
    _var = "_var"
    
    # bar.py
    
    from foo import *
    
    print(dir())  # list of defined objects, contains 'var' but not '_var'
    print(var)    # var
    print(_var)   # NameError: name '_var' is not defined
    
  • _ : the single underscore is a special case of the leading single underscore variables. It is used by convention as a trash variable, to store a value that is not intended to be later accessed. It is also not imported by wildcard imports. Eg: this for loop prints "I must not talk in class" 10 times, and never needs to access the _ variable.

    for _ in range(10):
        print("I must not talk in class")
    
  • var_: single trailing underscore variables. They are classic variables used by convention to avoid conflicts with Python keyword. Eg:

    class_ = "MyClassName"
    
  • __var: double leading underscore variables (at least two leading underscores, at most one trailing underscore). When used as class attributes (variables and methods), these variables are subject to name mangling: outside of the class, python will rename the attribute to _<Class_name>__<attribute_name>. Example:

    class MyClass:
        __an_attribute = "attribute_value"
    
    my_class = MyClass()
    print(my_class._MyClass__an_attribute)  # "attribute_value"
    print(my_class.__an_attribute)  # AttributeError: 'MyClass' object has no attribute '__an_attribute'
    

    When used as variables outside a class, they behave like single leading underscore variables.

  • __var__: double leading and trailing underscore variables (at least two leading and trailing underscores). Also called dunders. This naming convention is used by python to define variables internally. Avoid using this convention to prevent name conflicts that could arise with python updates. Dunder variables behave like single leading underscore variables: they are not subject to name mangling when used inside classes, but are not imported in wildcard imports.

Answered   2023-09-21 08:11:07

If one really wants to make a variable read-only, IMHO the best way would be to use property() with only getter passed to it. With property() we can have complete control over the data.

class PrivateVarC(object):

    def get_x(self):
        pass

    def set_x(self, val):
        pass

    rwvar = property(get_p, set_p)  

    ronly = property(get_p) 

I understand that OP asked a little different question but since I found another question asking for 'how to set private variables' marked duplicate with this one, I thought of adding this additional info here.

Answered   2023-09-21 08:11:07

  • Just to add: using propeety as a method decorator is a bit cleaner. - anyone

Great answers and all are correct.I have provided simple example along with simple definition/meaning.

Meaning:

some_variable --► it's public anyone can see this.

_some_variable --► it's public anyone can see this but it's a convention to indicate private...warning no enforcement is done by Python.

__some_varaible --► Python replaces the variable name with _classname__some_varaible (AKA name mangling) and it reduces/hides it's visibility and be more like private variable.

Just to be honest here According to Python documentation

"“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python"

The example:

class A():
    here="abc"
    _here="_abc"
    __here="__abc"


aObject=A()
print(aObject.here) 
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable 
#print(aObject.__here)

Answered   2023-09-21 08:11:07

  • _ _some_varaible -- .... and it reduces/hides it's visibility and be more like private variable. No, name mangling is the point, it doesn't hide the method. - anyone

Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:

class parent(object):
    __default = "parent"
    def __init__(self, name=None):
        self.default = name or self.__default

    @property
    def default(self):
        return self.__default

    @default.setter
    def default(self, value):
        self.__default = value


class child(parent):
    __default = "child"

if you then create a child instance in the python REPL, you will see the below

child_a = child()
child_a.default            # 'parent'
child_a._child__default    # 'child'
child_a._parent__default   # 'parent'

child_b = child("orphan")
## this will show 
child_b.default            # 'orphan'
child_a._child__default    # 'child'
child_a._parent__default   # 'orphan'

This may be obvious to some, but it caught me off guard in a much more complex environment

Answered   2023-09-21 08:11:07

Single leading underscores is a convention. there is no difference from the interpreter's point of view if whether names starts with a single underscore or not.

Double leading and trailing underscores are used for built-in methods, such as __init__, __bool__, etc.

Double leading underscores w/o trailing counterparts are a convention too, however, the class methods will be mangled by the interpreter. For variables or basic function names no difference exists.

Answered   2023-09-21 08:11:07

Your question is good, it is not only about methods. Functions and objects in modules are commonly prefixed with one underscore as well, and can be prefixed by two.

But __double_underscore names are not name-mangled in modules, for example. What happens is that names beginning with one (or more) underscores are not imported if you import all from a module (from module import *), nor are the names shown in help(module).

Answered   2023-09-21 08:11:07

  • Furthermore, names beginning with one or more underscores that have two or more trailing underscores behave as any other name again. - anyone

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

reference https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

Answered   2023-09-21 08:11:07

  • _ is much more similar to for example internal in c# then to private. Double underscore it much more similar to private then underscore is to private I would say. - anyone

Getting the facts of _ and __ is pretty easy; the other answers express them pretty well. The usage is much harder to determine.

This is how I see it:

_

Should be used to indicate that a function is not for public use as for example an API. This and the import restriction make it behave much like internal in c#.

__

Should be used to avoid name collision in the inheritace hirarchy and to avoid latebinding. Much like private in c#.

==>

If you want to indicate that something is not for public use, but it should act like protected use _. If you want to indicate that something is not for public use, but it should act like private use __.

This is also a quote that I like very much:

The problem is that the author of a class may legitimately think "this attribute/method name should be private, only accessible from within this class definition" and use the __private convention. But later on, a user of that class may make a subclass that legitimately needs access to that name. So either the superclass has to be modified (which may be difficult or impossible), or the subclass code has to use manually mangled names (which is ugly and fragile at best).

But the problem with that is in my opinion that if there's no IDE that warns you when you override methods, finding the error might take you a while if you have accidentially overriden a method from a base-class.

Answered   2023-09-21 08:11:07

In the case of methods, you can use the double underscore to hide away private 'methods' with the following pattern:

# Private methods of MyClass
def _MyClass__do_something(obj:'MyClass'):
    print('_MyClass__do_something() called. type(obj) = {}'.format(type(obj)))

class MyClass():
    def __init__(self):
        __do_something(self)

mc = MyClass()

Output:

_MyClass__do_something() called. type(obj) = <class '__main__.MyClass'>

I stumbled across this today when I tried using double underscore for class methods and got the NameError: name '_<class><method>' is not defined error.

Answered   2023-09-21 08:11:07

To frame it in simple words, let us compare python's variables' accessibility conventions to access modifiers in Java:

(Python)                                     =   (Java)
_single_underscore_variable                  =   Protected (Accessible to class and its subclasses)
__double_underscore_variable                 =   Private (Accessible to class itself only)
no_underscore_variable                       =   Public (Accessible anywhere)

Reference: https://www.tutorialsteacher.com/python/public-private-protected-modifiers

Answered   2023-09-21 08:11:07