Qual è lo scopo della variabile di sottolineatura singola "_" in Python?


618

Qual è il significato di _after forin questo codice?

if tbh.bag:
   n = 0
   for _ in tbh.bag.atom_set():
      n += 1


5
Nel tuo caso, sarebbe più pulito len(tbh.bag.atom_set())(se il valore restituito ha un __len__metodo) oppuresum(1 for _ in tbh.bag.atom_set())
Nick T

In pylintun'altra opzione per i nomi di variabili fittizie è un prefisso di dummy_per il nome della variabile. Utilizzando questo prefisso con pylint, pylintnon emette un avviso. Inoltre è possibile configurare il modello variabile fittizio per pylintadattarsi a cose come __.
Trevor Boyd Smith,

Risposte:


780

_ ha 4 principali usi convenzionali in Python:

  1. Per contenere il risultato dell'ultima espressione (/ istruzione) eseguita in una sessione di interprete interattiva. Questo precedente è stato impostato dall'interprete CPython standard e altri interpreti hanno seguito l'esempio
  2. Per la ricerca della traduzione in i18n (consultare il gettext documentazione di per esempio), come nel codice come: raise forms.ValidationError(_("Please enter a correct username"))
  3. Come general purpose "usa e getta" nome variabile per indicare che parte di risultato della funzione viene deliberatamente ignorato (Concettualmente, esso viene scartato.), Come nel codice come: label, has_label, _ = text.partition(':').
  4. Come parte della definizione di una funzione (utilizzando uno defo lambda), in cui la firma è fissa (ad es. Da un'API callback o della classe genitore), ma questa particolare implementazione della funzione non necessita di tutti i parametri, come nel codice come:callback = lambda _: True

(Per molto tempo questa risposta ha elencato solo i primi tre casi d'uso, ma il quarto caso è emerso abbastanza spesso, come notato qui , per valere la pena elencarlo esplicitamente)

Quest'ultimo "variabile usa o getta" utilizza i casi può essere in conflitto con il caso d'uso della ricerca della traduzione, quindi è necessario evitare l'uso _come variabile usa e getta in qualsiasi blocco di codice che lo utilizza anche per la traduzione i18n (molte persone preferiscono un doppio trattino basso , __come variabile usa e getta proprio per questo motivo).


19
Potresti spiegare come funziona in una chiamata di funzione, ad esempio: raise forms.ValidationError (_ ("Inserisci un nome utente corretto")) . L'ho visto nel codice Django e non è chiaro cosa stia succedendo.
Giovanni C,

41
Questo è l'utilizzo 2 - per convenzione, _è il nome utilizzato per la funzione che esegue ricerche di traduzione di stringhe di internazionalizzazione e localizzazione. Sono abbastanza sicuro che sia stata la gettextbiblioteca C a stabilire quella convenzione.
ncoghlan,

43
FWIW, ho iniziato a utilizzare personalmente __(un doppio trattino basso) come variabile generica usa e getta per evitare conflitti con uno dei primi due casi d'uso.
ncoghlan,

14
Le convenzioni delle comunità emergenti non tendono ad avere fonti autorevoli, ma solo osservazioni delle pratiche che sono apparse nel tempo. FWIW, sono uno dei co-autori degli aggiornamenti PEP 8 più recenti e la mia risposta si basa sui 3 modi diversi che ho visto _usato come nome variabile da quando ho iniziato a usare Python in modo professionale nel 2002.
ncoghlan,

12
La convenzione è principalmente per il disimballaggio della tupla: a, __, c = iterabledice immediatamente al lettore che stiamo disimballando una 3 tupla, ma usando solo il primo e l'ultimo valore. Se invece scriviamo a, b, c = iterable, il lettore (o un codice di Linter automatizzato) possono ragionevolmente aspettarsi di tutto a, be cper essere utilizzato in seguito (e se non lo sono, può essere un segno di un qualche bug).
ncoghlan,

207

È solo un nome di variabile ed è convenzionale in Python da utilizzare _per le variabili usa e getta. Indica semplicemente che la variabile loop non è effettivamente utilizzata.


5
vuoi dire che non rappresenta l'ultimo valore restituito?
alwbtc,

31
@steve solo in una shell di
Gabi Purcaru

4
simile all'uso di _ in Prolog
Matthias il

3
simile all'uso di ~ in Matlab
PatriceG

Si noti che nella shell di cpython, se definito in modo esplicito _, si interrompe permanentemente il valore di output dell'espressione precedente. Questo sembra orribilmente incoerente e gli standard di Python lang devono affrontare questo problema. Dovrebbero semplicemente definire _un nome usa e getta e impedirne l'utilizzo come identificatore reale.
theferrit32

78

Il carattere di sottolineatura _è considerato come variabile " I Don't Care " o " Throwaway " in Python

  • L'interprete python memorizza l'ultimo valore dell'espressione nella variabile speciale chiamata _.

    >>> 10 
    10
    
    >>> _ 
    10
    
    >>> _ * 3 
    30
  • Il carattere di sottolineatura _viene utilizzato anche per ignorare i valori specifici. Se non sono necessari i valori specifici o i valori non vengono utilizzati, è sufficiente assegnare i valori per sottolineare.

    Ignora un valore durante il disimballaggio

    x, _, y = (1, 2, 3)
    
    >>> x
    1
    
    >>> y 
    3

    Ignora l'indice

    for _ in range(10):     
        do_something()

2
C'è un terzo utilizzo, che è per la funzione di internazionalizzazione _("Hello world!").
Jeff Younker,

3
A livello di processore, c'è davvero differenza tra "per _ nell'intervallo" e "per x nell'intervallo" e quindi non usare x? O è solo per la leggibilità umana?
iammax,

1
@iammax Usando il dismodulo ho scoperto che non c'era differenza nel bytecode. I vantaggi della leggibilità umana sono evidenti, tuttavia.
Alistair Carscadden,

21

Ci sono 5 casi per usare il trattino basso in Python.

  1. Per memorizzare il valore dell'ultima espressione nell'interprete.

  2. Per ignorare i valori specifici. (il cosiddetto "Non mi interessa")

  3. Dare significati e funzioni speciali al nome di variabili o funzioni.

  4. Da utilizzare come funzioni "Internazionalizzazione (i18n)" o "Localizzazione (l10n)".

  5. Per separare le cifre del valore letterale numerico.

Ecco un bell'articolo con esempi di mingrammer .


2
In realtà è abbastanza nuovo blog.pythonlibrary.org/2017/01/11/...
MichaelChirico

3

Per quanto riguarda le lingue Python, _non ha alcun significato speciale. È un identificatore valido proprio come _foo, foo_o_f_o_o_ .

Qualsiasi significato speciale di _è puramente per convenzione. Diversi casi sono comuni:

  • Un nome fittizio quando non si intende utilizzare una variabile, ma è richiesto un nome da sintassi / semantica.

    # iteration disregarding content
    sum(1 for _ in some_iterable)
    # unpacking disregarding specific elements
    head, *_ = values
    # function disregarding its argument
    def callback(_): return True
  • Molte REPL / shell memorizzano il risultato dell'ultima espressione di livello superiore in builtins._.

    L'identificatore speciale _viene utilizzato nell'interprete interattivo per memorizzare il risultato dell'ultima valutazione; è memorizzato nel builtinsmodulo. Quando non è in modalità interattiva, _non ha un significato speciale e non è definito. [ fonte ]

    A causa del modo in cui i nomi vengono cercati, a meno che non sia ombreggiato da una _definizione globale o locale a cui si _fa riferimento nudo builtins._.

    >>> 42
    42
    >>> f'the last answer is {_}'
    'the last answer is 42'
    >>> _
    'the last answer is 42'
    >>> _ = 4  # shadow ``builtins._`` with global ``_``
    >>> 23
    23
    >>> _
    4

    Nota: alcune shell come ipythonnon assegnano builtins._ma un caso speciale _.

  • Nel contesto di internazionalizzazione e localizzazione, _viene utilizzato come alias per la funzione di traduzione primaria.

    gettext.gettext (messaggio)

    Restituisce la traduzione localizzata del messaggio, in base all'attuale dominio globale, lingua e directory locale. Questa funzione è in genere definita come _ () nello spazio dei nomi locale (vedere gli esempi seguenti).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.