Usage of underscores
There are 5 usages of underscores (_
) in python
Single leading underscore _var
_var
is intended for internal use.from M import *
doesn’t import objects whose names start with an underscore.
# m.py
external = "external"
_internal = "internal"
# main1.py - doesn't work
from m import *
print(external)
# external
print(_internal)
# NameError: name '_internal' is not defined
# main2.py - work
from m import external, _internal
print(external)
# external
print(_internal)
# internal
# main3.py - work
import m
print(m.external)
# external
print(m._internal)
# internal
- Single leading underscore is used a lot in classes. Programmers can create private variables and methods
class Time:
def __init__(self, year, month, day):
self.year = year
self.month = month
self._day = day
def _is_even_number(self, x):
return x % 2 == 0
time = Time(2020, 7, 10)
print(time.year, time.month, time._day)
print(time._is_even_number(10))
2020 7 10
True
Visual seperator of digits
amount = 1_000_000.1
print(amount)
1000000.1
Values we don’t care about
for _ in range(3):
print("I don't care about index")
I don't care about index
I don't care about index
I don't care about index
year, *_, second = (2020, 7, 10, 12, 10, 59)
print(_)
[7, 10, 12, 10]
Single Trailing Underscore var_
Only use to avoid conflicts with Python keywords.
import keyword
print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
global_=2
Double Leading Underscore __var
__var
will have a different name in the class where the python interpreter overwrites such identifiers in a class to avoid conflicts of names between the current class and its subclasses.
class Time:
def __init__(self, year, month):
self.year = year
self._month = month
self.__day = 1
time = Time(2020, 7)
print(dir(time))
['_Time__day', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_month', 'year']
print(time.__day)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-11-6ce3ac535632> in <module>
----> 1 print(time.__day)
AttributeError: 'Time' object has no attribute '__day'
print(time._Time__day)
1
Double Leading and Trailing Underscore var
Magic methods like __init__
, __call__
, __slots__
, can be overwritten
class Time:
def __init__(self, year, month):
self.year = year
self._month = month
self.__day = 1
def __str__(self):
return f"year: {self.year}, month: {self._month}, day: {self.__day}"
time = Time(2020,7)
print(time)
year: 2020, month: 7, day: 1