Unpacking* underscore (_) in python
Underscore is just not a character in python unlike to other programming languages where it is used for variable name, function names. In python it is used widely with different significance and impact to python programs.
Lets see 5 different usages of underscore and their impact on python programs.
- To ignore values which are unimportant.
- To store last value in REPL shell.
- To assign a special values to function or variable.
- Splitting numbers.
- As an alias for internationalization and localization functions.
Lets discuss in details with examples
Underscore variables to ignore values
Underscoring is most commonly used to ignore values; when _ is used as variable when we do not want to use this variable at later point.
- Ignore the index for loop
for _ in range(5):
print("Hi")
- For iterating and assigning values out of tuples/list etc.
>>> tuple = (0,1,2,3,4,5,6,7,8,9) >>> for _ in tuple: print(tuple) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> for _ in tuple: print(_) 0 1 2 3 4 5 6 7 8 9
- Ignore when unpacking
>>> x,_,_,y = (1,2,3,4) >>> print(x,y) 1 4
# This is an example of extended unpacking, where multiple values can be ignored # This is available for python 3.x >>> a, *_, b = (7,6,5,4,3,2,1) >>> print(a,b) 7 1
Use in REPL Shell to store value of last expression
>>> 5+4 9 >>> _ # stores values of last evaluated expression 9 >>> _+6 15 >>> a = _ # assign _ to another variable >>> a 15
Separating digits of number
>>> decimal = 1_000_000 >>> binary = 0b_0010 >>> octa = 0o_64 >>> hexa = 0x_23_ab >>> print(decimal) 1000000 >>> print(binary) 2 >>> print(octa) 52 >>> print(hexa) 9131
Naming of functions and variables
- Single pre underscore: _var
The underscore prefix is meant as a hint to tell another programmer that a variable or method starting with a single underscore is intended for internal use.
class Book:
def __init__(self, title, author, price, pages):
self.title = title
# properties
self.author = author
self.price = price
self.pages = pages
self._internalTxt = "This is to be used for internal use"
book1 = Book('War and peace', 'leo Tolstoy', 528, 1225)
print(book1.title)
print(book1._internalTxt)
Single pre underscore does not stop from accessing the single pre underscore variable
War and peace This is to be used for internal use
Process finished with exit code 0
However leading underscore do have an impact how names get imported from modules. Variables starting with an underscore will be ignored while import *
>>> from my_functions import * >>> func() 'Book' >>> _private_func() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '_private_func' is not defined
- Single post underscore : var_
This can be used to avoid conflicts while naming variable with keywords.
>>> def function(def): SyntaxError: invalid syntax >>> def function(def_): pass
>>>
Note: The naming patterns so far receive their meaning from agreed-upon conventions only.
- Double pre underscore: __var
With double pre underscore tells python interpreter to rewrite the attribute name of subclasses to avoid naming conflicts.
*Name Mangling - python interpreter alters the variable name in way that it is challenging to clash when class in inherited.
>>> class person(): def __init__(self): self.name = "Ram" self.age = 30 self.__ID = 375669 >>> person1 = person() >>> dir(person1) ['__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__', '_person__ID', 'age', 'name']
dir returns all the attributes of class object, look at the list of variables in attributes list.
self.name and self.age appears on the list without any change.
look at self.__ID, in the list of attributes it is rewritten as _person__ID to avoid overridding of variables in subclasses. This is called name mangling .
- Double pre and post underscore: __var__
Variables surrounded by a double underscore prefix and postfix are left unscathed by the Python interpreter. In Python different names which start and end with the double underscore. They are called as magic methods or dunder methods (topic for some another day). These are reserved for special use in the language. This rule covers things like __init__ for object constructors, or __call__ to make objects callable etc.
>>> class Sample(): def __init__(self): self.__num__ = 7 >>> obj = Sample() >>> print(obj.__num__) 7
Great content
Private