How do I convert a string to an f-string?

I read this Python blog about the new f-lines and they seem really neat. However, I want to be able to load the f-string from a string or file.

I cannot find any string method or other function that does this.

From the example in my link above:

name = 'Fred' age = 42 f"My name is {name} and I am {age} years old" 'My name is Fred and I am 42 years old' 

But what if I had a string s ? I want to be able to effectively s , something like this:

 name = 'Fred' age = 42 s = "My name is {name} and I am {age} years old" effify(s) 

It turns out that I can already do something similar to str.format and get a performance boost. Namely:

 format = lambda name, age: f"My name is {name} and I am {age} years old" format('Ted', 12) 'My name is Ted and I am 12 years old' 
+19
source share
3 answers

f lines are code. Not only in the safe, β€œof course, a string literal is a code”, but also a dangerous, arbitrary way to execute code. This is a valid string f:

 f"{__import__('os').system('install ransomware or something')}" 

and he will execute arbitrary shell commands when evaluating.

You ask how to take a line loaded from a text file and evaluate it as code, and the answer comes down to eval . This, of course, is a security risk and probably a bad idea , so I recommend not trying to load f-lines from files.

If you want to load f-string f"My name is {name} and I am {age} years old" from the file, then actually put

 f"My name is {name} and I am {age} years old" 

in the file, f and quotation marks are all.

Read it from the file, compile it and save it (so eval does not need to recompile it every time):

 compiled_fstring = compile(fstring_from_file, '<fstring_from_file>', 'eval') 

and evaluate it with eval :

 formatted_output = eval(compiled_fstring) 

If you do this, be very careful with the sources from which you will load your f-lines.

+15
source

But what if I had a string s? I want to be able to, something like this:

 name = 'Fred' age = 42 s = "My name is {name} and I am {age} years old" effify(s) 

AFAIU, According to PEP 498 - Interpolation of letter strings , this is impossible 1 . There is no way to programmatically create an f-string:

In Python source code, an f-string is a literal string prefixed with 'f' that contains expressions inside curly braces .


1 Unless, of course, you want to use something like exec , as mentioned in @coldspeed. But at this point, the cons probably outweigh the pros.

+6
source

A simple solution would be to use f-lines and eval.

 def effify(non_f_str: str): return eval(f'f"""{non_f_str}"""') name = 'Fred' age = 42 s = "My name is {name} and I am {age} years old" effify(s) 'My name is Fred and I am 42 years old' 

This basically adds β€œf” to the line and then evaluates to code. Triple quotes also help place multi-line strings. The function will try to pull the variables referenced in the f-line from the area around its call. As already mentioned, using eval can be dangerous, but if you know your source, then I think this is no more dangerous than executing any other code.

+5
source

Source: https://habr.com/ru/post/1273449/


All Articles