1

I'd like to build a tool where fstring formats are stored in a configuration file.

config = load_config()

def build_fstring(str):
  return ...   # <-- issue is there

chosen_format = config.get("chosen_format")  # returns '{k},{v}'

fstring = build_fstring(chosen_format) # may return something like 'f"{k},{v}"'

for (k,v) in d.items():
  print(fstring)  # fstring is evaluated here

My issue is that fstring is compiled before variables are known.

Is there a way to do it ?

Setop
  • 2,262
  • 13
  • 28

2 Answers2

4

According to PEP-498, f-strings are meant to "provide a way to embed expressions inside string literals", which means that f-strings are first and foremost string literals, and that trying to evaluate the value of a variable as an f-string defeats its very purpose.

For your purpose of using a variable as a string formatting template, it would be easier to use the str.format method instead:

k, v = 1, 2
chosen_format = '{k},{v}'
print(chosen_format.format(**locals()))

This outputs:

1,2
blhsing
  • 91,368
  • 6
  • 71
  • 106
0

I found a trick using eval:

config = load_config()

chosen_format = config.get("chosen_format")  # returns '{k},{v}'

for (k,v) in d.items():
  print(eval('f"'+chosen_format+'"'))

But I not very satisfied by the cleanness of the code - print should not know how to build the content - and the performance of evaluating code for each record.

Setop
  • 2,262
  • 13
  • 28
  • Well, this is sort of what you are stuck with, when you want to dynamically execute source code. If you want something more elegant, you are going to have to think of a more elegant approach. It is quite strange to have a configuration file with f-strings. – juanpa.arrivillaga Jul 26 '22 at 09:38
  • 1
    It will work, but I'll strongly recommend using the method in the answer given by blhsing. In general using eval is a bad practice and can be insecure depending of the source of it's parameters. For more info check here : https://stackoverflow.com/a/1832957/11260467 – Xiidref Jul 26 '22 at 10:06