places - python print f
cadenas f en Python 3.6 (4)
Realmente me gusta profundizar en el estilo de código y es interesante saber si de ahora en adelante en todos los casos sería mejor usar el nuevo estilo.
Estoy usando mucho el
.format()
en mis proyectos de Python 3.5, y me temo que quedará en desuso durante las próximas versiones de Python debido a este nuevo tipo de literales de cadena.
>>> name = "Test"
>>> f"My app name is {name}."
''My app name is Test.''
¿La función de cadena formateada reemplaza completamente el
format()
?
Entiendo que se basa en la idea de que:
Simple es mejor que complejo.
Sin embargo, ¿qué pasa con los problemas de rendimiento? ¿Existe alguna diferencia entre ellos? ¿O es simplemente un aspecto simple de la misma característica?
Me temo que quedará en desuso durante las próximas versiones de Python
No lo
str.format
,
str.format
no parece (ni tiene una razón) para irse en el
str.format
plazo, el PEP que introdujo
f
cadenas prefijadas incluso
afirma en su Resumen
:
Este PEP no propone eliminar o desaprobar ninguno de los mecanismos de formateo de cadenas existentes.
Se introdujeron cadenas formateadas para abordar algunas de las deficiencias que tenían otros métodos para formatear cadenas; no tirar los viejos métodos y forzar a Dios sabe cuántos proyectos usar f-string si quieren que su código funcione para Python 3.6+.
En cuanto al rendimiento de estos, parece que mi sospecha inicial de que podrían ser más lentos es incorrecta, las cadenas f parecen superar fácilmente a sus contrapartes
.format
:
➜ cpython git:(master) ./python -m timeit -s "a = ''test''" "f''formatting a string {a}''"
500000 loops, best of 5: 628 nsec per loop
➜ cpython git:(master) ./python -m timeit "''formatting a string {a}''.format(a=''test'')"
100000 loops, best of 5: 2.03 usec per loop
Estos se realizaron contra la rama maestra del repositorio de CPython a partir de este escrito; definitivamente están sujetos a cambios:
-
f-strings
, como una nueva característica, pueden tener posibles optimizaciones -
Las optimizaciones para CPython pueden hacer que
.format
más rápido (por ejemplo, el método Speedup llama a 1.2x )
Pero realmente, no te preocupes tanto por la velocidad, preocúpate por lo que es más legible para ti y para los demás.
En muchos casos, serán
f-strings
, pero
hay algunos casos
en los que el
format
es mejor.
Para aprovechar la respuesta de Jim y abordar su problema de rendimiento, utilicé el módulo
dis
de Python para comparar las instrucciones de código de bytes para dos funciones sintácticamente diferentes, pero funcionalmente equivalentes.
import dis
def f1():
a = "test"
return f"{a}"
def f2():
return "{a}".format(a=''test'')
print(dis.dis(f1))
print(dis.dis(f2))
El resultado de lo cual es:
11 0 LOAD_CONST 1 (''test'') 2 STORE_FAST 0 (a) 12 4 LOAD_FAST 0 (a) 6 FORMAT_VALUE 0 8 RETURN_VALUE None 15 0 LOAD_CONST 1 (''{a}'') 2 LOAD_ATTR 0 (format) 4 LOAD_CONST 2 (''test'') 6 LOAD_CONST 3 ((''a'',)) 8 CALL_FUNCTION_KW 1 10 RETURN_VALUE None
Se puede ver que la cadena f maneja el formato sin llamadas a atributos o funciones, lo que puede imponer la verificación de tipos y la sobrecarga de memoria.
Según
timeit
esto da como resultado una ganancia de rendimiento aproximadamente 3x (para mis funciones específicas)
>>> timeit.timeit(''f1()'', ''from __main__ import f1'', number=100000) 0.012325852433775708 >>> timeit.timeit(''f2()'', ''from __main__ import f2'', number=100000) 0.036395029920726074
Si desea seguir admitiendo Python 3.5, puede usar
fstring
pip install fstring
from fstring import fstring
x = 1
y = 2.0
plus_result = "3.0"
print fstring("{x}+{y}={plus_result}")
# Prints: 1+2.0=3.0
Una cosa que no se menciona (lo que hace imposible la desaprobación de las técnicas antiguas) es que la interpolación es solo para literales de cadena. Es decir, la cadena se representa una vez en tiempo de ejecución. La plantilla no se puede volver a utilizar con variables actualizadas, por ejemplo:
str_template.format(args)
Otro caso es i18n, donde se usa string.Template. Muchos casos de uso serían imposibles sin las técnicas más antiguas. Disfrute de la interpolación de cadenas, pero no la use donde no sea apropiado, es decir, lugares donde necesite una plantilla reutilizable.