Quale stile usare per i parametri di restituzione non utilizzati in una chiamata di funzione Python

27

Esiste uno stile di codifica raccomandato / generalmente accettato per la gestione di situazioni in cui una funzione restituisce una tupla di valori, ma solo uno di questi valori viene utilizzato in seguito (si noti che questo è principalmente destinato alle funzioni di libreria che non posso cambiare - scrittura un involucro attorno alla chiamata è probabilmente un po 'eccessivo ...)? Invece di fare

a, b, c = foo()

e quindi non usare b e c , quale delle seguenti varianti dovrebbe essere preferita (o ce n'è un'altra?):

Variante 1 (trattino basso)

a, _, _ = foo()

(che è molto chiaro e semplice ma potrebbe scontrarsi con _ = gettext.gettext utilizzato in molte applicazioni che usano la traduzione)

Variante 2 (nome fittizio)

a, unused, unused = foo()

(non molto allettante, penso, lo stesso vale per altri nomi come dummy )

Variante 3 (indice)

a = foo()[0]

(a me il ()[0] sembra non-pythonic ...)

    
posta user49643 13.03.2012 - 19:22
fonte

6 risposte

15

L'uso del trattino basso per le variabili non utilizzate è decisamente accettabile. Attenzione però, in alcune codebase non è un'opzione in quanto quell'identificatore è riservato come abbreviazione di gettext . Questa è l'obiezione più frequente a questo stile (anche se non è un problema per la maggioranza, per quanto posso giudicare). Lo raccomanderei comunque, e lo uso sempre da solo.

Nomi come dummy o unused tendono a irritarmi personalmente, e non li vedo terribilmente spesso (in Python, cioè, conosco una base di codice Delphi che usa dummy liberamente, e ha anche trapelato negli script associati al programma in questione). Ti consiglio di non farlo.

Anche l'estrazione di un elemento dalla tupla restituita va bene. Inoltre salva alcuni problemi con il giusto numero di valori inutilizzati. Nota però che ha due potenziali svantaggi:

  • Non esplode se il numero di valori è diverso da quello che ti aspetti. potrebbe essere utile per rilevare mixaggi e errori di battitura
  • Funziona solo quando il valore di ritorno è una sequenza (sono principalmente tuple e liste, ma restiamo in generale). A mano a mano, conosco una classe nel mio codice (un vettore 2D) che è iterabile e produce un numero costante di valori (e quindi può essere utilizzato negli incarichi di decompressione), ma non è indicizzabile.
risposta data 13.03.2012 - 19:57
fonte
19

Pylint mi ha fatto prendere l'abitudine di farlo in questo modo:

widget, _parent, _children = f()

Cioè, i risultati non utilizzati hanno un nome descrittivo preceduto da _. Pylint considera gli utenti locali con prefisso _ come inutilizzato e globali o attributi con prefisso _ come privato.

    
risposta data 14.03.2012 - 05:17
fonte
3

Se nel tuo intero progetto, lo stai facendo solo una volta o molto raramente per la particolare funzione, userei Variant 1 se sai che gettext non è un problema in quel modulo, e altrimenti Variant 3.

D'altra parte, se lo facessi molto - e specialmente se ogni volta vuoi un sottoinsieme diverso dei valori di ritorno (facendo in modo che un wrapper restituisca quelli a cui tieni non interessa ), potrebbe essere utile scrivere un wrapper che inserisca i risultati in una tupla denominata , o un'istanza di qualche altra classe descrittiva, che ti permetterebbe di fare:

bar = foo()

E poi lavora con bar.a , bar.b e bar.c .

    
risposta data 14.03.2012 - 07:54
fonte
1

Sono un programmatore non Python, ma per me la terza variante ha più senso.

Nella variante 3 hai assolutamente chiaro quali valori sei interessato a trattare. Nelle varianti 1 e 2, si assegnano i valori alle variabili e, quindi, possono essere utilizzati. Potresti averli nominati in modo oscuro, ma la scarsa nomenclatura non è in realtà una soluzione a qualsiasi problema.

A parte la chiarezza, perché dovresti voler assegnare valori non utilizzati a uno slot in memoria (come nelle varianti 1 e 2)? Questa sarebbe una soluzione scadente in termini di gestione della memoria.

    
risposta data 13.03.2012 - 19:34
fonte
1

Come altri hanno già detto, il carattere di sottolineatura ( _ ) è lo standard. Ma se il carattere di sottolineatura viene utilizzato per le traduzioni, penso che la doppia sottolineatura sia l'alternativa migliore.

var, __, value = "VAR=value".partition('=')

Meglio di questi:

var, unused, value = "VAR=value".partition('=')

var, unused_del, value = "VAR=value".partition('=')

var, _del, value = "VAR=value".partition('=')

    
risposta data 29.05.2015 - 18:49
fonte
-2

Ecco una regola generale: se viene utilizzato solo 1 dei valori restituiti, perché non restituire semplicemente quel valore 1? Nel caso in cui il flag venga chiamato da più posti, tieni un flag per lo stesso e restituisci i valori come per il flag.

Modifica

Nel caso in cui fossi nella tua situazione, e non avessi scritto la funzione, forse avrei optato per Variant 2. Manterrei i nomi fittizi lì in modo che i parametri possano essere utilizzati in caso di necessità. Affettare una lista avrà un piccolo overhead. Forse puoi risparmiare qualche byte per ricevere i dati indesiderati.

    
risposta data 13.03.2012 - 19:26
fonte

Leggi altre domande sui tag