I was reading this blog post on Python's new f-strings and they seem really neat. However, I want to be able to load an f-string from a string or file.
I can't seem to find any string method or other function that does this.
From the example in the blog post:
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 eff-ify s
, something like this:
name = 'Fred'
age = 42
s = "My name is {name} and I am {age} years old"
effify(s)
It turns out I can already perform something similar to str.format
and garner the performance pick up. 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'
Essentially, you have three options; The first is to define a new line as a string variable and reference that variable in f-string curly braces. The second workaround is to use os. linesep that returns the new line character and the final approach is to use chr(10) that corresponds to the Unicode new line character.
F-String literals start with an f , followed by any type of strings (i.e. single quotation, double quotation, triple quotation), then you can include your Python expression inside the string, in between curly brackets. Let's string to use an f-String in your Python shell: name = "f-String" print(f"hello {name}!")
Strings in Python are usually enclosed within double quotes ( "" ) or single quotes ( '' ). To create f-strings, you only need to add an f or an F before the opening quotes of your string. For example, "This" is a string whereas f"This" is an f-String.
Also called “formatted string literals,” f-strings are string literals that have an f at the beginning and curly braces containing expressions that will be replaced with their values.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With