HOWTO · Python

Resuelva el TypeError: no todos los argumentos se convirtieron durante el formato de cadena en Python

Este error puede aparecer cuando una cadena de formato con `%` no tiene marcadores que correspondan a todos los valores proporcionados. En este artículo veremos cómo identificar ese desajuste, distinguir el formato de cadenas del módulo numérico y elegir una forma correcta de dar formato, incluida la diferencia entre los marcadores `%` y las llaves de `.format()`.

En esta página

El error TypeError: not all arguments converted during string formatting suele indicar que Python interpretó % como formato de cadenas de estilo antiguo y encontró valores que los especificadores de formato de la cadena no consumieron. El mismo operador también calcula el módulo numérico, así que importan los tipos y las posiciones de los operandos: si a la izquierda de % hay una cadena, se aplica el formato de cadenas. Comprueba primero qué operación se está realizando y después verifica que cada marcador de posición tenga un valor compatible. Los ejemplos muestran cómo distinguir estos casos y elegir un estilo de formato coherente.

Qué significa este TypeError

Con números, % devuelve el resto de una división. Si a la izquierda hay una cadena, % aplica el formato de estilo antiguo: marcadores como %s y %d indican los valores que se insertarán en esa cadena. Por tanto, el significado de la expresión depende del operando izquierdo, no de que el derecho parezca numérico.

Una cadena como "19" sigue siendo texto. En "19" % 10, Python interpreta el lado izquierdo como una cadena de formato; como no hay ningún marcador que consuma 10, muestra TypeError: not all arguments converted during string formatting. Para calcular un resto, convierte primero el texto en un entero. Para incluir texto en un mensaje, usa un marcador de formato.

Comprueba cómo se está usando el operador %

Una causa frecuente es aplicar % a texto obtenido con input() o escrito entre comillas. Convierte la entrada numérica con int() antes de calcular el módulo. En cambio, si lo que quieres es dar formato a una cadena, déjala a la izquierda y añade un marcador de posición correspondiente.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

message = "%s scored %d points." % ("Mina", 18)
print(message)

El ejemplo da formato a un nombre y a un entero, y produce Mina scored 18 points. Ese texto visible permanece en inglés porque el bloque de código canónico no se modifica.

Para calcular el módulo numérico, convierte la entrada antes de hacer la operación. Este ejemplo captura el texto del error para la cadena sin convertir y, a continuación, muestra el resultado numérico:

age_text = "19"
try:
    age_text % 10
except TypeError as error:
    print(type(error).__name__ + ": " + str(error))

age = int(age_text)
print(age % 10)

La llamada a int() convierte los dígitos en un entero; es una función de conversión, no un especificador de formato de cadenas. Una cadena con contenido no numérico no se puede convertir de este modo, así que valida la entrada o gestiona los errores de conversión cuando no sea de confianza.

Haz coincidir los especificadores de formato con los valores

El formato de estilo antiguo requiere un valor compatible para cada marcador de posición. Cuando el lado derecho es una tupla, los valores se asignan a los marcadores en orden. Si hay más valores que marcadores, un valor sobrante puede provocar el TypeError indicado. Si hay menos valores, Python muestra otro error de formato; los desajustes en el número de valores no producen todos el mismo mensaje.

Por ejemplo, dos marcadores %s requieren dos valores. Quita el valor sobrante o añade otro marcador si ese valor debe aparecer en el resultado. Usa %s para texto y %d para un entero. Elige un especificador adecuado para el valor, en lugar de suponer que todo desajuste tiene la misma causa.

Usa un solo estilo de formato de cadenas a la vez

El formato con % consume marcadores %s o %d. El método .format() consume llaves como {}. Para el formato con %, las llaves por sí solas son caracteres normales; por eso, una cadena que contiene {0} no consume un valor pasado a %.

Elige un método para la expresión. Con .format(), llama al método sobre la plantilla y pásale los valores. Con %, incluye en la plantilla los marcadores porcentuales correspondientes y proporciona los valores a la derecha. Las cadenas f también son una opción si la versión de Python las admite. No combines una plantilla con llaves y % esperando que se procesen ambos estilos de marcadores.

Verifica la expresión corregida

Lee la expresión de izquierda a derecha: identifica el tipo del operando izquierdo, decide si % significa módulo o formato, cuenta los marcadores de posición y compáralos con los valores proporcionados. Luego ejecuta la expresión corregida más pequeña posible y revisa el resultado. Si sigue apareciendo el mensaje indicado, comprueba si hay valores sobrantes o si se está usando una cadena donde se esperaba un número. Si aparece otro mensaje, analiza ese nuevo error por separado.

Para obtener más detalles, consulta la documentación de Python sobre entrada y salida, que también explica el formato de cadenas de estilo antiguo.