python - during - Nuevo estilo de formato con tupla como argumento
not all arguments converted during string formatting mysql (3)
¿Por qué no puedo usar tuple como argumento para formatear en un nuevo estilo ("cadena" .format ())? Funciona bien en estilo antiguo ("cadena"%)?
Este código funciona:
>>> 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.
Y esto no:
>>> 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''
Incluso 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
Aunque funciona de esa manera:
>>> 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.
La forma antigua de formateo usaba un operador binario, %
. Por su naturaleza, solo puede aceptar dos argumentos. La nueva forma de formatear usa un método. Los métodos pueden tomar cualquier cantidad de argumentos.
Como a veces es necesario pasar varias cosas para formatear y es un poco torpe crear tuplas con un elemento todo el tiempo, la forma antigua surgió con un truco: si lo pasa como una tupla, usará el contenido del tupla como las cosas para formatear. Si le pasa algo que no sea una tupla, usará eso como el único formato.
La nueva forma no necesita un hack tal como es un método, puede tomar cualquier cantidad de argumentos. Como tal, varias cosas para formatear tendrán que pasar como argumentos separados. Afortunadamente, puedes descomprimir una tupla en argumentos usando *
:
print("First item: {:d}, second item: {:d} and third item: {:d}.".format(*tuple))
En realidad, es posible usar una tupla como argumento para format()
, si indexas manualmente la tupla dentro de las llaves:
>>> 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.
Sin embargo, me parece menos claro que el enfoque *
.
Como explicó icktoofay , en el antiguo estilo de formateo, si pasabas una tupla, Python la descomprimiría automáticamente.
Sin embargo, no puede usar una tupla con el método str.format
porque Python cree que solo está transmitiendo un argumento. Tendría que descomprimir la tupla con el operador *
para pasar cada elemento como un argumento individual.
>>> 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.
Además, habrás notado que cambié el nombre de tu variable de tuple
a t
- no utilices nombres incorporados para las variables, ya que las sobreescribes y eso podría causar problemas en la pista.