Error de formato de texto: no se permite la alineación ‘=’ en el especificador de formato de cadena

¿Qué significa '=' alignment en el siguiente mensaje de error y por qué lo causa este código?

 >>> "{num:03}".format(num="1") Traceback (most recent call last): File "", line 1, in  ValueError: '=' alignment not allowed in string format specifier 

El código tiene un problema sutil: el valor de entrada "1" es texto, no un número. Pero el mensaje de error no parece tener nada que ver con eso.

No hay nada en el mensaje de error que indique por qué “’=’ alineación” es relevante y no aparece en el código. Entonces, ¿cuál es el significado de emitir ese mensaje de error?

El mensaje de error aparece porque el especificador de formato ha implícito la '=' alignment .

El str.format mini-lenguaje de la especificación de formato str.format ha decidido el especificador de alineación “=” porque:

Si se precede el campo de ancho con un carácter cero (‘0’), se habilitará el relleno cero para los tipos numéricos. Esto es equivalente a un carácter de relleno de ‘0’ con un tipo de alineación de ‘=’.

Por lo tanto, al especificar 0N como “relleno cero a ancho N”, ha implicado que “la entrada es de tipo numérico” y que “los ceros deben ir entre el signo y los dígitos”. Esta última implicación es lo que se entiende por '=' alignment .

Como el valor "1" no es numérico, el código de manejo de alineación “=” genera esa excepción. El mensaje está escrito esperando que sepa de qué se está hablando porque solicitó (por implicación) la alineación “=”.

Sí, creo que ese mensaje de error necesita ser mejorado. He planteado un problema para eso .

Una solución es usar '>' relleno '>' (justificar a la derecha), que es con la syntax:

 [[fill]align][width] 

con alinear siendo > , relleno siendo 0 y ancho siendo 3 .

 >>> "{num:0>3}".format(num="1") '001' 

El problema fue que hay un 0 diferente en la especificación de formato:

 format_spec ::= [[fill]align][sign][#][0][width][grouping_option][.precision][type] # ^^^ This one 

Ese cero simplemente hace que se fill defecto a 0 y se align a = .

= alineación se especifica como:

Hace que el relleno se coloque después de la señal (si existe) pero antes de los dígitos. Esto se utiliza para imprimir campos en el formulario ‘+000000120’. Esta opción de alineación solo es válida para los tipos numéricos. Se convierte en el valor predeterminado cuando ‘0’ precede inmediatamente al ancho del campo.

Fuente (documentos de Python 3)

Esto espera que el argumento sea un int , ya que las cadenas no tienen signos. Así que simplemente lo configuramos manualmente al valor predeterminado normal de > (justificar a la derecha).

También tenga en cuenta que 0 solo especifica los valores predeterminados para fill y align . Puedes cambiar ambos o solo la alineación.

 >>> # fill defaults to '0', align is '>', `0` is set, width is `3` >>> "{num:>03}".format(num=-1) '0-1' >>> # fill is `x`, align is '>', `0` is set (but does nothing), width is `"3"` >>> "{num:x>03}".format(num=-1) 'x-1' >>> # fill is `x`, align is '>', `0` is set (but does nothing), width is `"03"` (3) >>> "{num:x>003}".format(num=-1) 'x-1' 

str.__format__ no sabe qué hacer con su parte 03 . Eso solo funciona con números:

 >>> "{num:03}".format(num=1) '001' 

Si realmente quieres poner a cero una cadena, puedes usar rjust :

 >>> "1".rjust(3, "0") '001' 

Está intentando insertar ‘string -> “1” donde se requiere un float-> 3.44. Elimine las comillas “1”, es decir, num = 1, y funcionará

Este formato sería aceptable.

 "{num}:03".format(num="1") 

pero la forma en que ha especificado el marcador de posición {num:03} no lo es. Sin embargo, ese es un ValueError interesante, si elimina el : el error interesante es reemplazado por un KeyError estándar.