How do I convert a string into an f-string?
f-strings are code. Not just in the safe, "of course a string literal is code" way, but in the dangerous, arbitrary-code-execution way. This is a valid f-string:
f"{__import__('os').system('install ransomware or something')}"
and it will execute arbitrary shell commands when evaluated.
You're asking how to take a string loaded from a text file and evaluate it as code, and the answer boils down to eval
. This is of course a security risk and probably a bad idea, so I recommend not trying to load f-strings from files.
If you want to load the f-string f"My name is {name} and I am {age} years old"
from a file, then actually put
f"My name is {name} and I am {age} years old"
in the file, f
and quotation marks and all.
Read it from the file, compile it and save it (so eval
doesn't have 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 about the sources you load your f-strings from.
A simple solution would be to use f-strings 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 prepends an "f" to the string and then evaluates as code. The triple quotes help to accommodate multiline strings as well. The function will try to pull the variables referenced in the f-string from the scope around its call. As pointed out, using eval
can potentially be dangerous, but if you know your source, then I think it is not more dangerous than executing any other code.
But what if I had a string s? I want to be able to eff-ify s, 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 -- Literal String Interpolation, this isn't possible1. There's no way to programmatically create an f-string:
In Python source code, an f-string is a literal string, prefixed with 'f', which contains expressions inside braces.
1Unless of course, you'd be willing to use something like exec
as @coldspeed mentioned. But at that point, the cons probably outweigh the pros.