Why do some functions have underscores "__" before and after the function name?
Asked Answered
O

7

589

This "underscoring" seems to occur a lot, and I was wondering if this was a requirement in the Python language, or merely a matter of convention?

Also, could someone name and explain which functions tend to have the underscores, and why (__init__, for instance)?

Observation answered 31/12, 2011 at 18:57 Comment(4)
@AustinHenley: Not for double underscores before and after the name. You're thinking of underscores solely before the name.Ratcliffe
Related: "What is the historical reason why Python uses the double underscore for Class Private members?".Campy
Possible duplicate of What is the meaning of a single- and a double-underscore before an object name?Toenail
@Toenail Note that this question asks about underscores before and after the name, and the duplicate target that you proposed asks about underscores only before the name. Though, I admit that some of the answers there cover this case as well.Heliotrope
A
790

From the Python PEP 8 -- Style Guide for Python Code:

Descriptive: Naming Styles

The following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):

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

  • single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.

    Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

  • __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.

Note that names with double leading and trailing underscores are essentially reserved for Python itself: "Never invent such names; only use them as documented".

Analysand answered 31/12, 2011 at 19:1 Comment(6)
Raymond also explains why you'd want the name mangling behavior starting at around 34 minutes into this video: youtube.com/watch?v=HTLu2DFOdTgLineberry
So the choice between the single leading underscore and double leading underscore in a name is a bit like choosing between protected and private in C++ and Java? _single_leading_underscore can be changed by children, but __double_leading_underscore can't?Valuer
__double_leading_underscore is still public, the variable is simply renamed to avoid a clash.Inadvertent
The new mangled method name, having a single leading underscore, is private. E.g. __boo becomes _FooBar__booFivefinger
Talking about "double leading and trailing underscores" part of the answer, what does "magic" mean here? When you say "use them as documented", what am I using them for? Did you mean, "These are a methods which python is meant to call, not you" ?Boomer
@BenSlade I think the crucial part is "Never invent such names". If you write class Thing: def __foo__(self): ..., the Python developers may add the magic method __foo__ to the definition of object in a new Python version and whatever that method is supposed to do won't work for your Thing after updating Python.Emir
B
88

The other respondents are correct in describing the double leading and trailing underscores as a naming convention for "special" or "magic" methods.

While you can call these methods directly ([10, 20].__len__() for example), the presence of the underscores is a hint that these methods are intended to be invoked indirectly (len([10, 20]) for example). Most python operators have an associated "magic" method (for example, a[x] is the usual way of invoking a.__getitem__(x)).

Beethoven answered 31/12, 2011 at 20:5 Comment(0)
R
33

Names surrounded by double underscores are "special" to Python. They're listed in the Python Language Reference, section 3, "Data model".

Rolland answered 31/12, 2011 at 19:1 Comment(1)
Finally, a fast pointer from Google to the right part of the Python reference manual. Thank you.Impetuosity
C
12

Added an example to understand the use of __ in python. Here is the list of All __

https://docs.python.org/3/genindex-all.html#_

Certain classes of identifiers (besides keywords) have special meanings. Any use of * names, in any other context, that does not follow explicitly documented use, is subject to breakage without warning

Access restriction using __

"""
Identifiers:
-  Contain only (A-z, 0-9, and _ )
-  Start with a lowercase letter or _.
-  Single leading _ :  private
-  Double leading __ :  strong private
-  Start & End  __ : Language defined Special Name of Object/ Method
-  Class names start with an uppercase letter.
-

"""


class BankAccount(object):
    def __init__(self, name, money, password):
        self.name = name            # Public
        self._money = money         # Private : Package Level
        self.__password = password  # Super Private

    def earn_money(self, amount):
        self._money += amount
        print("Salary Received: ", amount, " Updated Balance is: ", self._money)

    def withdraw_money(self, amount):
        self._money -= amount
        print("Money Withdraw: ", amount, " Updated Balance is: ", self._money)

    def show_balance(self):
        print(" Current Balance is: ", self._money)


account = BankAccount("Hitesh", 1000, "PWD")  # Object Initalization

# Method Call
account.earn_money(100)

# Show Balance
print(account.show_balance())

print("PUBLIC ACCESS:", account.name)  # Public Access

# account._money is accessible because it is only hidden by convention
print("PROTECTED ACCESS:", account._money)  # Protected Access

# account.__password will throw error but account._BankAccount__password will not
# because __password is super private
print("PRIVATE ACCESS:", account._BankAccount__password)

# Method Call
account.withdraw_money(200)

# Show Balance
print(account.show_balance())

# account._money is accessible because it is only hidden by convention
print(account._money)  # Protected Access
Caines answered 28/1, 2020 at 12:7 Comment(1)
Is there a place that documents the use of leading __ as strong private? I don't see it in the linked document, nor under the link in that document to __ identifiers. Single leading underscore is documented there; double leading underscore for class private names using name mangling is documented there; but it seems calling __ "super private" is misleading, and may lead to people using it on file-level functions, where as far as I know it actually has no meaning.Ogdon
S
7

Actually I use _ method names when I need to differ between parent and child class names. I've read some codes that used this way of creating parent-child classes. As an example I can provide this code:

class ThreadableMixin:
   def start_worker(self):
       threading.Thread(target=self.worker).start()

   def worker(self):
      try:
        self._worker()
    except tornado.web.HTTPError, e:
        self.set_status(e.status_code)
    except:
        logging.error("_worker problem", exc_info=True)
        self.set_status(500)
    tornado.ioloop.IOLoop.instance().add_callback(self.async_callback(self.results))

...

and the child that have a _worker method

class Handler(tornado.web.RequestHandler, ThreadableMixin):
   def _worker(self):
      self.res = self.render_string("template.html",
        title = _("Title"),
        data = self.application.db.query("select ... where object_id=%s", self.object_id)
    )

...

Svensen answered 30/8, 2015 at 16:43 Comment(1)
Isn't this what the double underscore prefix is for?Angwantibo
K
5

This convention is used for special variables or methods (so-called “magic method”) such as __init__ and __len__. These methods provides special syntactic features or do special things.

For example, __file__ indicates the location of Python file, __eq__ is executed when a == b expression is executed.

A user of course can make a custom special method, which is a very rare case, but often might modify some of the built-in special methods (e.g. you should initialize the class with __init__ that will be executed at first when an instance of a class is created).

class A:
    def __init__(self, a):  # use special method '__init__' for initializing
        self.a = a
    def __custom__(self):  # custom special method. you might almost do not use it
        pass
Kathiekathleen answered 17/1, 2019 at 17:57 Comment(0)
C
2

In Python, the use of an underscore in a function name indicates that the function is intended for internal use and should not be called directly by users. It is a convention used to indicate that the function is "private" and not part of the public API of the module. However, it is not enforced by the language and can still be called by the user if they choose to do so.

Cultivable answered 17/1, 2023 at 11:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.