Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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'
like image 459
piRSquared Avatar asked Nov 16 '17 21:11

piRSquared


People also ask

How do I change strings to f-string?

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.

How do you convert a string to an F-string in Python?

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}!")

How do you make an F-string?

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.

What is f-string formatting?

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.


3 Answers

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.

like image 140
user2357112 supports Monica Avatar answered Oct 16 '22 12:10

user2357112 supports Monica


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.

like image 25
Jarno Avatar answered Oct 16 '22 10:10

Jarno


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.

like image 9
Christian Dean Avatar answered Oct 16 '22 10:10

Christian Dean