2013-03-03 13 views
26

Perché non posso usare la tupla come argomento per il formattatore in un nuovo stile ("stringa" .format())? Funziona bene in vecchio stile ("stringa"%)?Nuovo stile di formattazione con tupla come argomento

Questo codice funziona:

>>> tuple = (500000, 500, 5) 
... print "First item: %d, second item: %d and third item: %d." % tuple 

    First item: 500000, second item: 500 and third item: 5. 

E questo non lo fa:

>>> tuple = (500000, 500, 5) 
... print("First item: {:d}, second item: {:d} and third item: {:d}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    ValueError: Unknown format code 'd' for object of type 'str' 

Anche con {r!}

>>> tuple = (500000, 500, 5) 
... print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(tuple)) 

    Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    IndexError: tuple index out of range 

Anche se funziona con questo modo:

>>> print("First item: {!r}, second item: {!r} and third item: {!r}." 
...  .format(500000, 500, 50)) 

    First item: 500000, second item: 500 and third item: 5. 

risposta

45

Il vecchio modo di formattazione utilizzato un operatore binario, %. Per sua natura, può accettare solo due argomenti. Il nuovo modo di formattazione utilizza un metodo. I metodi possono accettare un numero qualsiasi di argomenti.

Dato che a volte è necessario passare più cose per formattare ed è un po 'maldestro creare tuple con un oggetto per tutto il tempo, il modo in vecchio stile ha prodotto un trucco: se lo si passa come una tupla, verrà utilizzato il contenuto della tupla come le cose da formattare. Se passi qualcosa di diverso da una tupla, la userà come unica cosa da formattare.

Il nuovo modo non ha bisogno di un simile attacco: poiché è un metodo, può richiedere un numero qualsiasi di argomenti. Di conseguenza, più cose da formattare dovranno essere passate come argomenti separati. Fortunatamente, è possibile decomprimere una tupla in argomenti utilizzando *:

print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple)) 
17

Come icktoofay spiegato, nel vecchio stile di formattazione, se hai superato in una tupla, Python sarebbe decomprimere automaticamente.

Tuttavia, non è possibile utilizzare una tupla con il metodo str.format perché Python pensa che si passi solo un argomento. Dovresti decomprimere la tupla con l'operatore * per passare in ciascuno degli elementi come argomento individuale.

>>> t = (500000, 500, 5) 
>>> "First item: {:d}, second item: {:d} and third item: {:d}.".format(*t) 
First item: 500000, second item: 500 and third item: 5. 

Inoltre, si sarebbe accorto ho rinominato la variabile tuple-t - non utilizzare nomi built per le variabili, come si sarà loro sovrascrivere e che potrebbe causare problemi lungo la pista.

+3

+1 per rinominare la variabile. –

+1

@Volatility Penso che {: d} non sia necessario. Se vuoi ordinare i dati puoi usare semplicemente {} o specificare l'ordine con indice o dati in tuple {0} {1} {2} – GeoStoneMarten

+0

@GeoStoneMarten mentre sono d'accordo, usando '{: d} 'indica più chiaramente che tu vuoi un numero decimale lì (per qualcun altro che legge il tuo codice) – Petzku

0

In realtà è possibile usare una tupla come argomento per format(), se si indice manualmente la tupla all'interno delle parentesi graffe:

>>> t = (500000, 500, 5) 
>>> print("First item: {0[0]:d}, second item: {0[1]:d} and third item: {0[2]:d}.".format(t)) 
First item: 500000, second item: 500 and third item: 5. 

ho trovato questo meno chiara rispetto all'approccio *, però.

Problemi correlati