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)?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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,__boobecomes_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”.
Method 2
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)).
Method 3
Names surrounded by double underscores are “special” to Python. They’re listed in the Python Language Reference, section 3, “Data model”.
Method 4
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)
)
…
Method 5
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
Method 6
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0