Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

169
Views
¿Cómo posponer/diferir la evaluación de f-strings?

Estoy usando cadenas de plantillas para generar algunos archivos y me encanta la concisión de las nuevas cadenas f para este propósito, para reducir mi código de plantilla anterior de algo como esto:

 template_a = "The current name is {name}" names = ["foo", "bar"] for name in names: print (template_a.format(**locals()))

Ahora puedo hacer esto, reemplazando directamente las variables:

 names = ["foo", "bar"] for name in names: print (f"The current name is {name}")

Sin embargo, a veces tiene sentido tener la plantilla definida en otro lugar: más arriba en el código, o importada de un archivo o algo así. Esto significa que la plantilla es una cadena estática con etiquetas de formato. Algo tendría que pasarle a la cadena para decirle al intérprete que interprete la cadena como una nueva cadena f, pero no sé si existe tal cosa.

¿Hay alguna forma de traer una cadena y hacer que se interprete como una cadena f para evitar usar la .format(**locals()) ?

Idealmente, quiero poder codificar así... (donde magic_fstring_function es donde entra la parte que no entiendo):

 template_a = f"The current name is {name}" # OR [Ideal2] template_a = magic_fstring_function(open('template.txt').read()) names = ["foo", "bar"] for name in names: print (template_a)

... con esta salida deseada (sin leer el archivo dos veces):

 The current name is foo The current name is bar

... pero el resultado real que obtengo es:

 The current name is {name} The current name is {name}
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Aquí tienes un "Ideal 2" completo.

No es un f-string, ni siquiera usa f-strings, pero hace lo solicitado. Sintaxis exactamente como se especifica. No hay dolores de cabeza de seguridad ya que no estamos usando eval() .

Utiliza una pequeña clase e implementa __str__ , que se llama automáticamente por impresión. Para escapar del alcance limitado de la clase, usamos el módulo de inspect para saltar un cuadro hacia arriba y ver las variables a las que tiene acceso la persona que llama.

 import inspect class magic_fstring_function: def __init__(self, payload): self.payload = payload def __str__(self): vars = inspect.currentframe().f_back.f_globals.copy() vars.update(inspect.currentframe().f_back.f_locals) return self.payload.format(**vars) template = "The current name is {name}" template_a = magic_fstring_function(template) # use it inside a function to demonstrate it gets the scoping right def new_scope(): names = ["foo", "bar"] for name in names: print(template_a) new_scope() # The current name is foo # The current name is bar
over 4 years ago · Santiago Trujillo Report

0

Una forma concisa de evaluar una cadena como una cadena f (con todas sus capacidades) es usar la siguiente función:

 def fstr(template): return eval(f"f'{template}'")

Entonces puedes hacer:

 template_a = "The current name is {name}" names = ["foo", "bar"] for name in names: print(fstr(template_a)) # The current name is foo # The current name is bar

Y, a diferencia de muchas otras soluciones propuestas, también puede hacer:

 template_b = "The current name is {name.upper() * 2}" for name in names: print(fstr(template_b)) # The current name is FOOFOO # The current name is BARBAR
over 4 years ago · Santiago Trujillo Report

0

Esto significa que la plantilla es una cadena estática con etiquetas de formato.

Sí, esa es exactamente la razón por la que tenemos literales con campos de reemplazo y .format , para que podamos reemplazar los campos cuando queramos llamando a format en él.

Algo tendría que pasarle a la cadena para decirle al intérprete que interprete la cadena como una nueva cadena f

Ese es el prefijo f/F . Podría envolverlo en una función y posponer la evaluación durante el tiempo de la llamada, pero por supuesto eso genera una sobrecarga adicional:

 template_a = lambda: f"The current name is {name}" names = ["foo", "bar"] for name in names: print (template_a())

Que imprime:

 The current name is foo The current name is bar

pero se siente mal y está limitado por el hecho de que solo puede mirar el espacio de nombres global en sus reemplazos. Intentar usarlo en una situación que requiere nombres locales fallará miserablemente a menos que se pase a la cadena como argumentos (lo que supera totalmente el punto).

¿Hay alguna forma de traer una cadena y hacer que se interprete como una cadena f para evitar usar la .format(**locals()) ?

Aparte de una función (limitaciones incluidas), no, también podría quedarse con .format .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!