Ga naar hoofdinhoud

Rol van underscore (_) in Python-tutorial

In deze tutorial leer je over het gebruik van underscore (_) in Python.
· 8 min lezen

Verken met AI

Voer de code van deze tutorial online uit en bewerk deze

Code uitvoeren

Veel Python-developers kennen de functionaliteiten van de underscore (_) in Python niet. Het helpt je om Python-code productief te schrijven.

Underscore (_) is een uniek teken in Python.

Als je een Python-programmeur bent, dan ben je waarschijnlijk bekend met de volgende syntaxis:

  • for _ in range(100)

  • __init__(self)

  • _ = 2

Het heeft in verschillende situaties een speciale betekenis. Laten we ze allemaal bekijken.

Je vindt maximaal zes verschillende toepassingen van de underscore (_). Als je wilt, kun je die voor verschillende doelen gebruiken zodra je een idee hebt van de underscore (_).

1. Gebruik in de interpreter

Python slaat de waarde van de laatste expressie in de interpreter automatisch op in een speciale variabele met de naam "_". Je kunt deze waarde ook aan een andere variabele toekennen als je wilt.

Je kunt het als een normale variabele gebruiken. Zie het voorbeeld

>>> 5 + 4
9
>>> _     # stores the result of the above expression
9
>>> _ + 6
15
>>> _
15
>>> a = _  # assigning the value of _ to another variable
>>> a
15

2. Waarden negeren

Underscore (_) wordt ook gebruikt om waarden te negeren. Als je specifieke waarden bij het uitpakken niet wilt gebruiken, wijs die waarde dan toe aan underscore (_).

Negeren betekent de waarden toekennen aan de speciale variabele underscore (_). We wijzen de waarden toe aan underscore (_) met de intentie die later in de code niet te gebruiken.

Zie het voorbeeld

## ignoring a value
a, _, b = (1, 2, 3) # a = 1, b = 3
print(a, b)

## ignoring multiple values
## *(variable) used to assign multiple value to a variable as list while unpacking
## it's called "Extended Unpacking", only available in Python 3.x
a, *_, b = (7, 6, 5, 4, 3, 2, 1)
print(a, b)
1 3
7 1

3. Gebruik in lussen

Je kunt underscore (_) als variabele in lussen gebruiken. Zie de onderstaande voorbeelden voor een idee.

## lopping ten times using _
for _ in range(5):
    print(_)

## iterating over a list using _
## you can use _ same as a variable
languages = ["Python", "JS", "PHP", "Java"]
for _ in languages:
    print(_)

_ = 5
while _ < 10:
    print(_, end = ' ') # default value of 'end' id '\n' in python. we're changing it to space
    _ += 1
0
1
2
3
4
Python
JS
PHP
Java
5 6 7 8 9

4. Cijfers van getallen scheiden

Als je een lang getal hebt, kun je de cijfers groeperen zoals je wilt voor een betere leesbaarheid.

Bijv.: million = 1_000_000

Daarnaast kun je underscore (_) gebruiken om de binaire, octale of hexadecimale onderdelen van getallen te scheiden.

Bijv.: binary = 0b_0010, octa = 0o_64, hexa = 0x_23_ab

Voer alle bovenstaande voorbeelden uit om de resultaten te zien.

## different number systems
## you can also check whether they are correct or not by coverting them into integer using "int" method
million = 1_000_000
binary = 0b_0010
octa = 0o_64
hexa = 0x_23_ab

print(million)
print(binary)
print(octa)
print(hexa)
1000000
2
52
9131

5. Benoemen met underscore (_)

Underscore (_) kan worden gebruikt om variabelen, functies en klassen te benoemen, enz.

  • Enkele pre-underscore: _variable
  • Enkele post-underscore: variable_
  • Dubbele pre-underscores: __variable
  • Dubbele pre- en post-underscores: __variable__

5.1. _single_pre_underscore

_name

Enkele pre-underscore wordt gebruikt voor intern gebruik. De meesten van ons gebruiken het daarom niet vaak.

Zie het volgende voorbeeld.

class Test:

    def __init__(self):
        self.name = "datacamp"
        self._num = 7

obj = Test()
print(obj.name)
print(obj._num)
datacamp
7

Enkele pre-underscore verhindert niet dat je toegang krijgt tot de variabele met enkele pre-underscore.

Maar enkele pre-underscore beïnvloedt de namen die uit de module worden geïmporteerd.

Schrijf de volgende code in het bestand my_funtions.

## filename:- my_functions.py

def func():
    return "datacamp"

def _private_func():
    return 7

Als je nu alle methoden en namen uit my_functions.py importeert, importeert Python de namen die beginnen met een enkele pre-underscore niet.

>>> from my_functions import *
>>> func()
'datacamp'
>>> _private_func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_private_func' is not defined

Je voorkomt de bovenstaande fout door de module normaal te importeren.

>>> import my_functions
>>> my_functions.func()
'datacamp'
>>> my_functions._private_func()
7

Enkele pre-underscore is uitsluitend bedoeld voor intern gebruik.

5.2 single_postunderscore

name_

Soms, als je Python-keywords als variabele-, functie- of classnamen wilt gebruiken, kun je hiervoor deze conventie gebruiken.

Je kunt conflicten met Python-keywords vermijden door een underscore aan het einde van de naam toe te voegen die je wilt gebruiken.

Laten we het voorbeeld bekijken.

>>> def function(class):
  File "<stdin>", line 1
    def function(class):
                 ^
SyntaxError: invalid syntax
>>> def function(class_):
...     pass
...
>>>

Enkele post-underscore wordt gebruikt om je variabelen te benoemen als Python-keywords en botsingen te vermijden door aan het einde van je variabelenaam een underscore toe te voegen.

5.3. Dubbele pre-underscore

__name

Dubbele pre-underscores worden gebruikt voor name mangling.

Dubbele pre-underscores vertellen de Python-interpreter om de attribuutnaam in subclasses te herschrijven om naamconflicten te vermijden.

  • Name mangling: de Python-interpreter past de variabelenaam zó aan dat een conflict lastig wordt wanneer de class wordt geërfd.

Laten we een voorbeeld bekijken.

class Sample():

    def __init__(self):
        self.a = 1
        self._b = 2
        self.__c = 3
obj1 = Sample()
dir(obj1)
['_Sample__c',
 '__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__',
 '_b',
 'a']

De bovenstaande code geeft alle attributen van het class-object terug. Laten we onze variabelen in de attributenlijst bekijken.

De variabele self.a verschijnt ongewijzigd in de lijst.

De variabele self._b verschijnt ook ongewijzigd in de lijst. Zoals hierboven besproken is die alleen bedoeld voor intern gebruik.

  • Staat de variabele self.__c in de lijst?

    • Als je goed naar de attributenlijst kijkt, vind je een attribuut _Sample__c. Dit is name mangling. Het dient om het overschrijven van de variabele in subclasses te voorkomen.

Laten we een andere class maken door de class Sample te erfen om te zien hoe overschrijven werkt.

class SecondClass(Sample):

    def __init__(self):
        super().__init__()
        self.a = "overridden"
        self._b = "overridden"
        self.__c = "overridden"
obj2 = SecondClass()
print(obj2.a)
print(obj2._b)
print(obj2.__c)
overridden
overridden



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-2-4bf6884fbd34> in <module>()
      9 print(obj2.a)
     10 print(obj2._b)
---> 11 print(obj2.__c)


AttributeError: 'SecondClass' object has no attribute '__c'

Hier werkt name mangling opnieuw. Het verandert obj2.__c in _SecondClass__c. Print dat element nu met het gewijzigde attribuut.

print(obj2._SecondClass__c)
overridden

Zie je, het werkt. Je kunt ook toegang krijgen tot de eerder gemaakte variabele via _Sample__c. Kijk maar:

print(obj1._Sample__c)
3

Je kunt toegang krijgen tot variabelen met dubbele pre-underscore via methoden in de class. Zie een voorbeeld.

class SimpleClass:

    def __init__(self):
        self.__datacamp = "Excellent"

    def get_datacamp(self):
        return self.__datacamp

obj = SimpleClass()
print(obj.get_datacamp()) ## it prints the "Excellent" which is a __var
print(obj.__datacamp)     ## here, we get an error as mentioned before. It changes the name of the variable
Excellent



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-5-8006c0a9b061> in <module>()
      9 obj = SimpleClass()
     10 print(obj.get_datacamp()) ## it prints the "Excellent" which is a __var
---> 11 print(obj.__datacamp)     ## here, we get an error as mentioned before. It changes the name of the variable


AttributeError: 'SimpleClass' object has no attribute '__datacamp'

Je kunt de dubbele pre-underscore ook gebruiken voor methoden. Zie een voorbeeld.

class SimpleClass:

    def __datacamp(self):
        return "datacamp"

    def call_datacamp(self):
        return self.__datacamp()

obj = SimpleClass()
print(obj.call_datacamp()) ## same as above it returns the Dobule pre underscore method
print(obj.__datacamp())    ## we get an error here
datacamp



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-1-cd8ce2e83589> in <module>()
      9 obj = SimpleClass()
     10 print(obj.call_datacamp()) ## same as above it returns the Dobule pre underscore method
---> 11 print(obj.__datacamp())    ## we get an error here


AttributeError: 'SimpleClass' object has no attribute '__datacamp'

Bekijk name mangling nog op een andere manier. Eerst maken we een variabele met de naam _SimpleClass__name, en daarna proberen we die variabele te benaderen met de naam met dubbele pre-underscore.

Zie een voorbeeld.

_SimpleClass__name = "datacamp"

class SimpleClass:

    def return_name(self):
        return __name

obj = SimpleClass()
print(obj.return_name()) ## it prints the __name variable
datacamp

Begrijp je het concept? Zo niet, lees het dan nog eens.

5.4. Dubbele pre- en post-underscores

__name__

In Python vind je verschillende namen die beginnen en eindigen met een dubbele underscore. Dit zijn magic methods of dunder-methoden.

class Sample():

    def __init__(self):
        self.__num__ = 7

obj = Sample()
obj.__num__
7

Dit leidt tot conflicten als je deze namen als variabelen gebruikt. Blijf er dus het liefst bij uit de buurt.

Conclusie

Gefeliciteerd! Gelukt. Je hebt een van de saaiste concepten in Python doorlopen. Maar het helpt enorm wanneer je met geavanceerde code werkt.

De meeste mensen, ik ook, begrijpen dit concept niet bij de eerste keer lezen. Dus verlies je geduld niet en lees het opnieuw als je het niet in één keer snapt. Als je vragen over het artikel hebt, laat het dan gerust weten in de reacties.

Als je een Python-beginner bent, raad ik je aan deze cursus te volgen en dit artikel daarna opnieuw te lezen voor volledig begrip.

Bronnen:

Onderwerpen

Gerelateerd