Vai al contenuto principale

Ruolo dell’underscore (_) in Python – Tutorial

In questo tutorial imparerai gli usi dell’underscore (_) in Python.
Aggiornato 29 set 2026  · 8 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Esegui e modifica il codice da questo tutorial online

Esegui codice

Molti sviluppatori Python non conoscono a fondo le funzionalità dell'underscore (_) in Python. Eppure aiuta a scrivere codice Python in modo più produttivo.

L’underscore (_) è un carattere particolare in Python.

Se programmi in Python, probabilmente conosci già la seguente sintassi:

  • for _ in range(100)

  • __init__(self)

  • _ = 2

In contesti diversi ha significati specifici. Vediamoli tutti.

Troverai al massimo sei usi diversi dell’underscore (_). Una volta capito come funziona, puoi sfruttarlo per scopi differenti.

1. Uso nell’interprete

Python memorizza automaticamente il valore dell’ultima espressione nell’interprete in una variabile particolare chiamata "_". Se vuoi, puoi assegnare questo valore a un’altra variabile.

Puoi usarla come una variabile normale. Guarda l’esempio

>>> 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. Ignorare valori

L’underscore (_) si usa anche per ignorare dei valori. Se durante l’unpacking non vuoi usare determinati valori, assegna quei valori all’underscore (_).

Ignorare significa assegnare i valori alla variabile speciale underscore (_). Stiamo assegnando valori all’underscore (_) indicando che non li useremo nel codice successivo.

Guarda l’esempio

## 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. Uso nei loop

Puoi usare l’underscore (_) come variabile nei loop. Vedi gli esempi qui sotto per farti un’idea.

## 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. Separare le cifre dei numeri

Se hai un numero con molte cifre, puoi separarne i gruppi come preferisci per migliorare la leggibilità.

Es.: million = 1_000_000

Puoi anche usare l’underscore (_) per separare le parti binarie, ottali o esadecimali dei numeri.

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

Esegui tutti gli esempi sopra per vedere i risultati.

## 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. Denominazione usando l’underscore (_)

L’underscore (_) può essere usato per nominare variabili, funzioni e classi, ecc.

  • Underscore singolo iniziale: _variable
  • Underscore singolo finale: variable_
  • Doppio underscore iniziale: __variable
  • Doppio underscore iniziale e finale: __variable__

5.1. _single_pre_underscore

_name

L’underscore singolo iniziale si usa per l’uso interno. Proprio per questo motivo la maggior parte di noi non lo usa spesso.

Guarda il seguente esempio.

class Test:

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

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

L’underscore singolo iniziale non ti impedisce di accedere alla variabile con underscore singolo iniziale.

Ma l’underscore singolo iniziale influisce sui nomi che vengono importati da un modulo.

Scriviamo il seguente codice nel file my_funtions.

## filename:- my_functions.py

def func():
    return "datacamp"

def _private_func():
    return 7

Ora, se importi tutti i metodi e i nomi da my_functions.py, Python non importa i nomi che iniziano con un underscore singolo iniziale.

>>> 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

Eviti l’errore sopra importando il modulo in modo normale.

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

L’underscore singolo iniziale è pensato solo per l’uso interno.

5.2 single_postunderscore

name_

A volte, se vuoi usare le parole chiave di Python come nomi di variabili, funzioni o classi, puoi usare questa convenzione.

Puoi evitare conflitti con le parole chiave di Python aggiungendo un underscore alla fine del nome che vuoi usare.

Vediamo un esempio.

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

L’underscore singolo finale si usa per nominare variabili come parole chiave di Python ed evitare conflitti aggiungendo un underscore alla fine del nome.

5.3. Doppio underscore iniziale

__name

Il doppio underscore iniziale si usa per il name mangling.

Il doppio underscore iniziale dice all’interprete Python di riscrivere il nome degli attributi nelle sottoclassi per evitare conflitti di denominazione.

  • Name mangling: l’interprete di Python altera il nome della variabile in modo che sia difficile entrare in conflitto quando la classe viene ereditata.

Vediamo un esempio.

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']

Il codice sopra restituisce tutti gli attributi dell’oggetto class. Guardiamo le nostre variabili nell’elenco degli attributi.

La variabile self.a compare nell’elenco senza modifiche.

Anche la variabile self._b compare senza modifiche. Come detto sopra, è solo per uso interno.

  • C’è la variabile self.__c nell’elenco?

    • Se osservi attentamente l’elenco degli attributi, trovi un attributo chiamato _Sample__c. Questo è il name mangling. Serve a evitare l’override della variabile nelle sottoclassi.

Creiamo un’altra classe ereditando Sample per vedere come funziona l’override.

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'

Qui il name mangling entra di nuovo in gioco. Trasforma obj2.__c in _SecondClass__c. Ora stampa quell’elemento usando l’attributo modificato.

print(obj2._SecondClass__c)
overridden

Vedi? Ha funzionato. Puoi anche accedere alla variabile creata in precedenza usando _Sample__c. Vediamo

print(obj1._Sample__c)
3

Puoi accedere alle variabili con doppio underscore iniziale tramite metodi nella classe. Ecco un esempio.

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'

Puoi usare il doppio underscore iniziale anche per i nomi dei metodi. Ecco un esempio.

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'

Osserviamo il name mangling da un’altra prospettiva. Prima creiamo una variabile chiamata _SimpleClass__name, poi proviamo ad accedervi usando il nome con doppio underscore iniziale.

Vediamo un esempio.

_SimpleClass__name = "datacamp"

class SimpleClass:

    def return_name(self):
        return __name

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

Hai capito il concetto? Se no, prova a rileggerlo.

5.4. Doppio underscore iniziale e finale

__name__

In Python troverai diversi nomi che iniziano e finiscono con il doppio underscore. Sono chiamati magic methods o dunder methods.

class Sample():

    def __init__(self):
        self.__num__ = 7

obj = Sample()
obj.__num__
7

Se usi questi nomi come nomi di variabili, potresti creare conflitti. Quindi è meglio evitarli.

Conclusione

Complimenti! Ce l’hai fatta. Hai terminato uno degli argomenti più noiosi di Python. Ma è molto utile quando lavori con codice avanzato.

Molte persone, me compreso, non capiscono questo concetto alla prima lettura. Quindi non perdere la pazienza: rileggi se non ti è chiaro subito. Se hai dubbi sull’articolo, non esitare a scriverli nei commenti.

Se sei un principiante di Python, ti consiglio di seguire questo corso e poi rileggere questo articolo per una comprensione completa.

Risorse:

Argomenti
Python
Data Science

Corsi Python

Corso

Introduzione a Python

4 ore
7.1M
Impara le basi dell’analisi dei dati con Python in sole 4 ore. Questo corso online ti introduce all’interfaccia di Python e ai pacchetti più usati.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

blog

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

blog

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

blog

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Mostra AltroMostra Altro