Formato de cadena: % frente a .format frente a literal de cadena f

Resuelto NorthIsUp asked hace 13 años • 16 respuestas

Existen varios métodos de formato de cadenas:

  • Pitón <2.6:"Hello %s" % name
  • Python 2.6+: "Hello {}".format(name)   (usastr.format )
  • Python 3.6+: f"{name}"   (usa cadenas f)

¿Cuál es mejor y para qué situaciones?


  1. Los siguientes métodos tienen el mismo resultado, entonces, ¿cuál es la diferencia?

    name = "Alice"
    
    "Hello %s" % name
    "Hello {0}".format(name)
    f"Hello {name}"
    
    # Using named arguments:
    "Hello %(kwarg)s" % {'kwarg': name}
    "Hello {kwarg}".format(kwarg=name)
    f"Hello {name}"
    
  2. ¿Cuándo se ejecuta el formateo de cadenas y cómo evito una penalización en el rendimiento del tiempo de ejecución?


Si está intentando cerrar una pregunta duplicada que solo busca una forma de formatear una cadena, utilice ¿Cómo coloco el valor de una variable dentro de una cadena? .

NorthIsUp avatar Feb 23 '11 01:02 NorthIsUp
Aceptado

Para responder a su primera pregunta... .formatparece más sofisticado en muchos sentidos. Lo molesto %también es cómo puede tomar una variable o una tupla. Uno pensaría que lo siguiente siempre funcionaría:

"Hello %s" % name

sin embargo, si namesucede (1, 2, 3), arrojará un TypeError. Para garantizar que siempre se imprima, deberá hacer

"Hello %s" % (name,)   # supply the single argument as a single-item tuple

lo cual es simplemente feo. .formatno tiene esos problemas. Además, en el segundo ejemplo que diste, el .formatejemplo tiene un aspecto mucho más claro.

Úselo únicamente por compatibilidad con versiones anteriores de Python 2.5.


Para responder a su segunda pregunta, el formato de cadena ocurre al mismo tiempo que cualquier otra operación: cuando se evalúa la expresión de formato de cadena. Y Python, al no ser un lenguaje perezoso, evalúa las expresiones antes de llamar a funciones, por lo que la expresión log.debug("some debug info: %s" % some_info)primero evaluará la cadena, por ejemplo "some debug info: roflcopters are active", y luego se pasará esa cadena a log.debug().

Claudiu avatar Feb 22 '2011 18:02 Claudiu

Algo que el operador de módulo ( % ) no puede hacer, que yo sepa:

tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)

resultado

12 22222 45 22222 103 22222 6 22222

Muy útil.

Otro punto: format(), al ser una función, puede usarse como argumento en otras funciones:

li = [12,45,78,784,2,69,1254,4785,984]
print map('the number is {}'.format,li)   

print

from datetime import datetime,timedelta

once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8,  minutes=20)

gen =(once_upon_a_time +x*delta for x in xrange(20))

print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))

Resultados en:

['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984']

2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00
eyquem avatar Jun 13 '2011 20:06 eyquem

Suponiendo que está utilizando el loggingmódulo de Python, puede pasar los argumentos de formato de cadena como argumentos al .debug()método en lugar de formatearlo usted mismo:

log.debug("some debug info: %s", some_info)

lo que evita formatear a menos que el registrador realmente registre algo.

Wooble avatar Feb 22 '2011 19:02 Wooble

A partir de Python 3.6 (2016), puedes usar cadenas f para sustituir variables:

>>> origin = "London"
>>> destination = "Paris"
>>> f"from {origin} to {destination}"
'from London to Paris'

Tenga en cuenta el f"prefijo. Si intentas esto en Python 3.5 o anterior, obtendrás un archivo SyntaxError.

Consulte https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings

Colonel Panic avatar Apr 15 '2016 11:04 Colonel Panic

PEP 3101 propone reemplazar el %operador con el nuevo formato de cadena avanzado en Python 3, donde sería el predeterminado.

BrainStorm avatar Aug 01 '2011 03:08 BrainStorm