In this lesson, you’ll learn how to use f-strings, otherwise known as formatted string literals. They are available in Python 3.6 and above.

Here’s an example:

>>> name = "Bob"
>>> age = 10
>>> f"My name is {name}. I am {age} years old."
'My name is Bob. I am 10 years old'

If you want to learn more, check out Python 3’s f-Strings: An Improved String Formatting Syntax.

00:00 This will be a short video on f-strings, otherwise known as formatted string literals. Normally, you might do something like this if you want to print a string out.

00:09 Let’s just say we have age = 10 and name = "Bob".

00:16 Let’s say we want to print out the string— print() string, "My name is Bob.

00:23 I am 10 years old." As you can see, I don’t really do this very often, that’s why it’s a little bit slower. I think the syntax is like that. Cool!

00:36 It worked. "My name is Bob. I am 10 years old". Okay. So, that’s been there since the beginning of time. You might also know .format() as a little bit cleaner way to do it.

00:46 You could do something like {1} and {0}, or you don’t even need these, I think, and it will still work. Or, if you wanted it to be cleaner and it to be a little bit more explicit, you would do something like this. So, those are all good ways to format strings.

01:03 Now, in Python 3.6 and above, you can use f-strings, which are very similar, but you just put the word f in front, and then instead of all this stuff, you just remove it.

01:16 So, it will actually evaluate what is in the curly brackets, and then sub in the variable names. You can do stuff like { age + 5 }, so they’re actually just expressions. I mean, you could do the same in the .format(), here, or in here, but then it’s all in one line and it’s very easy to see, just left-to-right, f"My name is {name}. I am {age}"—but you’re adding 5"years old".

01:40 This is also useful for classes where you could have A class,

01:45 then define the __init__()we’ll just use this example with name and age. self.name = name, self.age = age,

01:56 make a __str__() method—or, I guess a __repr__() method is a little bit more explicit, and if __str__() does not exist, it will actually call __repr__().

02:04 This is just a little bit easier. Return a multiline f-string, f""" My name is {self.name}. I am {self.age + 5} years old """.

02:23 Now, if we instantiate A with "Bob"—or, I guess we had variables name and age and then printed it out—we get a nice multiline string.

02:33 If you didn’t want the newlines and the spaces and stuff, you could just do something like this.

02:40 And if you wanted it all in one line, you could do…

02:50 Cool! There is just one case where you might not want to use formatted strings, and that is when you’re dealing with user input. If you’re letting your user type something and that goes into the formatted string, they can gain access to variables that they shouldn’t be.

03:04 I’ll link an article below that shows that example. I’ll also link an article that goes way in-depth into how f-strings work. But I think this is just a nice way to show the interviewer that you know how to use f-strings, and it saves you a little bit of time. In the next video, you’ll learn about sorting lists.

Avatar image for James Uejio

James Uejio RP Team on April 26, 2020

f-strings were added in 3.6: realpython.com/python-f-strings/

Avatar image for James Uejio

James Uejio RP Team on April 27, 2020

If you want to learn more, here is a Real Python walkthrough video on f-strings: Python 3’s f-Strings: An Improved String Formatting Syntax

Avatar image for raulfz

raulfz on March 31, 2021

Hi James, thank you for your tutorial. I’d appreciate if you could point me to the video or article that shows why it’s dangerous to use f-string with user input that you mention in this video. Thank you

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on March 31, 2021

@raulfz f-strings let you evaluate arbitrary Python expressions such as executing system commands or file removal:

import os
f"{os.system('echo Hello > /home/user/file')}"

Imagine what would happen if a rogue user provided malicious input for your placeholders.

Avatar image for Antonio B De Leon

Antonio B De Leon on Aug. 28, 2021

Yikes, that makes sense and is very scary.

Avatar image for szymon

szymon on March 7, 2022

Shouldn’t __repr__ return an object representation the way it could be reconstructed? Just like this:

def __repr__:
    return f"A(name={name!r}, age={age!r})"

Putting human-readable string in there might teach some bad habits for less experienced programmers.

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on March 7, 2022

@szymon It’s not an absolute requirement, but you’re right. In general, .__repr__() should return a piece of Python code that can be evaluated to recreate an object with the same value.

Avatar image for Lucas Ribeiro

Lucas Ribeiro on Sept. 17, 2022

About the arbitrary execution, it could be solved if I enforce str(), e.g.:

f'My name is {str(input())}'
os.system('echo Hello > /home/user/file'
Out[10]: "My name is os.system('echo Hello > /home/user/file'"

Using print %s already enforces the input to be a string as well:

print ("My name is %s" % (input()))
"os.system('echo Hello > /home/user/file'"
My name is "os.system('echo Hello > /home/user/file'"

Become a Member to join the conversation.