Python Single and Double Underscore

Posted in /  

Python Single and Double Underscore

Vinay Khatri
Last updated on September 1, 2022

    In other programming languages, we use the underscore for the snake_casing variable names, but in Python, the underscore is used for more than a simple snake casing. In Python, underscores have special meanings, and you have seen many developers using them in multiple situations, and you might wonder why they have used _ underscore there.

    Many of the Python beginners and intermediate developers are not fully aware of all the underscore's roles and functionalities in Python. But in this, you will learn the basic and advanced use case of underscore in Python and how you can use them to become more productive with Python.

    Underscore used by Python Interpreter

    Many of you may not know that Python interpreters use the underscore to automatically store the expression executed by the interpreter. If we have not used any variable name to store the expression the interpreter use the _ to store it, not only that we can use the _ to get the last expression.

    >>> "Hello World"
    'Hello World'
    >>> _
    'Hello World'
    >>> _ + "Welcome to techgeekbuzz"
    'Hello WorldWelcome to techgeekbuzz'
    >>> _
    'Hello WorldWelcome to techgeekbuzz'
    >>>

    Underscore to ignore the value

    Many times when we unpack a tuple or list, we only want to access the one or two values from the list or tuple. In that case, instead of using a temporary variable name that we are never gonna use in our program, we can simply use the underscore and tell the Python interpreter that we will not be using that variable in our program. This is the most common practice that every Python developer does when he/she would not be using the variable in the program.

    Example

    #get only a and b ignore 3 and 4
    a, b , _ , _ = (1,2,3,4,)
    
    print(a)
    print(b)

    Output

    1
    2

    In the above example, instead of using two single underscores, we can also use * (asterisk) mark with _ for multiple arguments.

    #get only a and b, and ignore 3,4,5,6, and 7
    a, b , *_ = (1,2,3,4,5,6,7)
    
    print(a)
    print(b)

    Output

    1
    2

    Using underscore for ignoring values is just a convention, it does not mean that the value will not store in the underscore. Underscore is a valid variable name so the value will be stored in the underscore.

    #get only a and b, and ignore 3,4,5,6, and 7
    a, b , *_ = (1,2,3,4,5,6,7)
    
    print(a)
    print(b)
    print(_)

    Output

    1
    2
    [3, 4, 5, 6, 7]

    The underscore is Just to tell the other developers that the value is not be using throughout the program.

    Underscore with Loop

    Generally, we use an identifier while dealing with for and while loop, but in the case when we are not using the identifier inside the loop, instead of using a variable name we use the _ .

    Example

    for _ in range(10):
        print("Hello World")

    Output

    Hello World
    Hello World
    Hello World
    Hello World
    Hello World
    Hello World
    Hello World
    Hello World
    Hello World
    Hello World

    Separate Digits with underscores

    Python numeric value allows us to use underscore to separate the digit for better readability. Just by looking at the value, 10000000 you can not tell whether it is 1 million or 10 million. But when we use the underscore separator 10_000_000 now with a single glance you know that it's 10 million.

    Example

    >>> thousand = 1_000
    >>> million = 1_000_000
    >>> billion = 1_000_000_000
    >>> total = thousand + million + billion
    >>> total
    1001001000

    But when you apply the arithmetic operation on the underscore separated value or even print it you get results in the normal form not underscore separated.

    Naming Using single pre underscore (_name)

    In Python, we do not have the concept of access modifiers such as Private, Public, and Protected. In Python class everything is Public. But using the single pre underscore(single underscore before variable or function name) convention we can specify a class property and method as a Private attribute or method. Although it is just a convention which means we can actually access those single pre underscore values outside the class.

    Example

    class Test:
        def __init__(self):
            self._private_attribute = "Some private value"
    
        def _private_method(self):
            print("some private method")
    
    
    t = Test()
    
    #access class private data
    print(t._private_attribute)
    print(t._private_method())

    Output

    Some private value
    some private method

    Naming Using a single post underscore (name_)

    Many time we come across such variable name which is similar to the reserved keyword. So instead of using a reserved keyword, we can use the underscore after the variable name so it does not conflict with the Python reserved keyword name.

    Example

    class Student:
        def __init__(self, name, class_, age):
            self.name = name
            self.class_ = class_
            self.age = age
    
    rahul = Student("Rahul", "7th", 15)
    
    print(rahul.name)
    print(rahul.class_)
    print(rahul.age)

    Output

    Rahul
    7th
    15

    Naming Using a double pre underscore (__name)

    In the above section, we learned that we use a single underscore before a variable or function name to make it conventionally private. But putting __ double underscore before the variable or method name provides a special meaning to the variable or method when the interpreter executes the statement. The pre double underscore in python is used for the name mangling(avoid name clashes with names defined by subclasses). Let's understand it with an example

    class Student:
        def __init__(self, name, grade, id):
            self.name = name
            self._grade = grade
            self.__id = id

    Now let's create an object of Studnet and list out its all properties and methods using dir() method.

    >>> rahul = Student("Rahul", "7th", 234)
    >>> dir(rahul)
    ['_Student__id', ..........., '_grade', 'name']

    As you can see that there are no changes in the _grade and name properties, but the __id has changed to _Student__id. This is becaue of Python name mangling, the Python interpreter automatically changed the __id attribute to _Student__id so no subclass can override it. Even to access the __id property we need to specify it as _Student__id else we would receive the AttributeError.

    >>> rahul.name
    'Rahul'
    
    >>> rahul._grade
    '7th'
    
    >>> rahul.__id
    AttributeError: 'Student' object has no attribute '__id'
    
    >>> rahul._Student__id
    234

    Naming Using Double pre and Post underscores (__name__)

    Variable and method having a double underscore before and after their name are known as magic or dunder(double underscore) methods. These are the special methods and variables that get automatically assigned when the Python program executed by the interpreter. For example the __name__ variable automatically assigned to the "__main__" if the actual script is directly executed, if it is imported the __name__ variable of the script is assigned to the script name. Similarly, there are many dunder methods that get automatically associated with the class when an object of the class gets created.

    Example

    class test:
        pass
    t = test
    print(dir(t))
    print(__name__)

    Output

    ['__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__']
    __main__

    to know more about Python __name__ variable and __main__ statement click here .

    Conclusion

    The Python underscore is a very interesting concept, I hope you learned something from this article. We mostly use the underscore _ in Python to ignore variables or to make variables or methods private(conventionally). But for most cases, the underscore works as a normal variable name. When its come to double underscore we can see some serious Python stuff like Python name mangling and Python automatic variable and method assignments.

    People are also reading:

    Leave a Comment on this Post

    0 Comments