(Titolo e contenuto aggiornati dopo aver letto la risposta di Alex)E 'Pythonic per una funzione per restituire un iterabile o non iterabile a seconda del suo ingresso?
In generale, credo che sia considerata una forma errata (non-Pythonic) per una funzione a volte restituire un oggetto iterabile e talvolta singolo a seconda dei suoi parametri.
Per esempio struct.unpack
restituisce sempre una tupla anche se contiene solo un elemento.
Sto cercando di finalizzare l'API per un modulo e ho un paio di funzioni che possono prendere uno o più parametri (tramite *args
) come questo:
a = s.read(10) # reads 10 bits and returns a single item
b, c = s.read(5, 5) # reads 5 bits twice and returns a list of two items.
Quindi restituisce un singolo elemento, se c'è solo un parametro, altrimenti restituisce una lista. Ora penso che questo va bene e non è affatto confuso, ma ho il sospetto che gli altri possono essere in disaccordo.
Il caso d'uso più comune per queste funzioni potrebbe essere quella vogliono solo un singolo elemento restituito, in modo sempre restituendo una lista (o tupla) si sente male:
a, = s.read(10) # Prone to bugs when people forget to unpack the object
a = s.read(10)[0] # Ugly and it's not clear only one item is being returned
Un'altra opzione è quella di avere due funzioni:
a = s.read(10)
b, c = s.read_list(5, 5)
che è OK, ma ingombra l'API e richiede all'utente di ricordare il doppio di molte funzioni senza aggiungere alcun valore.
Quindi la mia domanda è: Qualche volta restituisce un oggetto iterabile e talvolta un singolo confuso e non-Pythonic? Se sì, qual è l'opzione migliore?
Aggiornamento: Penso che il consenso generale è che è molto cattivo solo restituire un iterabile volte. Credo che la migliore opzione per la maggior parte dei casi potrebbe essere quella di riportare sempre l'iterabile, anche se contenesse un solo elemento.
Detto questo, per il mio caso particolare, penso che andrò alla suddivisione in due funzioni (read(item)
/readlist(*items)
), il ragionamento è che penso che il caso di singolo articolo accadrà molto più spesso del caso di più oggetti , quindi rende più facile l'utilizzo e l'API cambia meno problematico per gli utenti.
Grazie a tutti.
+1. A volte essere una cosa e talvolta essere una lista di cose è di solito un errore. Python lo ha fatto per% -formatting e questo è ampiamente considerato un errore e una cattiva trappola. – bobince
Avevo paura che la gente lo dicesse: è brutto avere una lista quando hai chiesto solo un singolo oggetto! –
@Scot Griffiths: IMHO i potenziali bug causati dall'essere troppo intelligenti superano i problemi che una semplice variabile potrebbe causare. Perché non usare un metodo come'def read (a_tuple): 'invece di usare' * args'? – voyager