F-strings In Python: Everything You Need To Know
HTML-код
- Опубликовано: 9 июл 2024
- Python's F-strings are incredibly powerful. Knowing how to use them and taking advantage of their formatting options can significantly improve your ability to write logging messages and display information in an understandable manner. In this video, I'll take a deep dive into F-strings and demonstrate some of their uses.
➡️ Pendulum package: pendulum.eustace.io
👷 Join the FREE Code Diagnosis Workshop to help you review code more effectively using my 3-Factor Diagnosis Framework: www.arjancodes.com/diagnosis
💻 ArjanCodes Blog: www.arjancodes.com/blog.
🎓 Courses:
The Software Designer Mindset: www.arjancodes.com/mindset
The Software Designer Mindset Team Packages: www.arjancodes.com/sas
The Software Architect Mindset: Pre-register now! www.arjancodes.com/architect
Next Level Python: Become a Python Expert: www.arjancodes.com/next-level...
The 30-Day Design Challenge: www.arjancodes.com/30ddc
🛒 GEAR & RECOMMENDED BOOKS: kit.co/arjancodes.
👍 If you enjoyed this content, give this video a like. If you want to watch more of my upcoming videos, consider subscribing to my channel!
💬 Discord: discord.arjan.codes
🐦Twitter: / arjancodes
🌍LinkedIn: / arjancodes
🕵Facebook: / arjancodes
📱Instagram: / arjancodes
👀 Code reviewers:
- Yoriz
- Ryan Laursen
- James Dooley
- Dale Hagglund
🎥 Video edited by Mark Bacskai: / bacskaimark
🔖 Chapters:
0:00 Intro
1:07 What are F-strings?
1:26 Formatting numbers
5:27 Padding and alignment
8:58 (Data)classes, Str and Repr
13:01 Date and time formatting
16:11 Dealing with special characters
19:01 Printing variables for debugging purposes
20:09 Multiline strings & comments
21:20 F-strings performance
22:34 Advantages of Python f-strings
#arjancodes #softwaredesign #python
DISCLAIMER - The links in this description might be affiliate links. If you purchase a product or service through one of those links, I may receive a small commission. There is no additional charge to you. Thanks for supporting my channel so I can continue to provide you with free content each week!
👷 Join the FREE Code Diagnosis Workshop to help you review code more effectively using my 3-Factor Diagnosis Framework: www.arjancodes.com/diagnosis.
Oh, yes. My favorite dessert for fridays lunches: Arjan videos.
Enjoy :)
For sure. Best Python videos on RUclips!
@@OMGnotThatGuy I really enjoy how he puts valuable knowledge on his videos. Even simple things like f strings can be really rich subjects while being pleasing to watch. Today I learned a lot o things I didn't know, for example.
Great video! Maybe I missed it, but did Arjan mention using using braces inside braces for variables like number of spaces to use in alignments?
>>> list_of_words = ['a','bc','def']
2 just = len(max(list_of_words))
3 for word in list_of_words:
4 print(f"This word: {word:>{just}}")
This word: a
This word: bc
This word: def
Thanks! He didn't mention that and I've been looking for to do that a while ago.
Great tip, thanks!
There is only one case where Template strings are preferable over F-strings. While you are working with databases and sql queries f-strings could be easily injectable by sql injection attacks. Template strings can’t be injected.
One reason to use % templates is in logging functions: The logger can skip the variable evaluation if the logging is skipped. This would not work with fstrings. Also you can not put backslashes in fstrings. f"{'
'*3}" raises a SyntaxError
You can totally put backslashes inside f-strings, just not within the brackets.
the backslash can't be within the braces of the f-string expression, but you can include a string which contained a backslash escaped character. `x = '
'; print(f"{x*3}
")` is completely fine.
@@nigh_anxiety Thanks :)
07:35 It's a circumflex. In German, it is sometimes called "Dach" or more collquially, "Dacherl" which means "little roof" ^^
That's a new word for me. Very cool. Alternatively, the ^ symbol is also called a "caret", which is what I've always called it and I think is probably the most common term in English (US).
Circumflex is a diacritic, meaning it is used to describe situations where other characters are modified, like ê for example. The isolated character is called caret
That's great! I have been looking for such a complete and clear explanation for quite some time. That makes f strings so much more useful !
I watch Arjan in the morning with my coffee. He just has such a pleasant, relaxing voice. I don't often write anything large in Python anymore, but I use Python extensively in security tasks... these videos are always informative and contain little bits of info that are often overlooked. Arjan, I would watch a video on Pendulum in a heartbeat!
Thank you, glad you liked the video!
Thank you for taking the time to make this video. I have been looking for a video like this for a while.
Thanks so much Henry, glad the content is helpful!
Really love your videos! Interesting, fast, and useful. Plus the perfect length. Thanks so much for this.
Thanks so much, glad the content is helpful!
Thank you for the video. Seems worth mentioning: if your class implements __format__, then f"{var:str}" equals format(var "str"). In particular, the documentation for string.format and datetime.datetime.format may help explain many of the examples presented here.
Thank you Jean, glad you liked the video!
Thanks for this video! It's amazing to see a experienced programmer explaining in deph a concept that will considered for beginners.
Thank you so much, glad you liked the video!
Thank you Arjan. I have been using F-string for sometime now but didn't know how robust I could use them like you did in this video. In my most recent uploaded video I created a class for polynomial mathematical functions and F-string helped a lot in the development of the __str__ method.
My first encounter with f'strings, I needed to mimic real world address data for a project. So creating a a variable with random.choice() or random.random() all the way through was fun.
A names list for the street names, people name, and city names, a random number for street address and building or house number, random choice of apt/suite number, random zipcode etc. All in one fstring.
I think you read my mind. This is exactly what I was looking for! Thank you!
Thanks so much, glad the content is helpful! :)
Thanks for another great video. I've been watching your videos during my lunch break each day and they've really helped me with my "100 days of Python" course.
Thanks so much, Steve the content is helpful!
My favorite Python channel in youtube, thanks Arjan :)
Thanks Frank, happy you’re enjoying the content!
As always I love your videos, the only thing I’d prefer is if you could leave the example output on screen for one second or so longer, eg: datetime formatting section
When I need to study the code or output, I just hit spacebar (which pauses the video). If i don't need to see it, then the current editing style keeps things moving fast. So my preference is to stick with the current editing style
Thanks for dataclasses man, very useful and only you spot it for me
Thanks so much, glad the content is helpful!
I wasn't sure how you were gonna talk about f-strings for 20 minutes, but you made me realize how much I don't know, and every minute count. Amazing video as always Arjan
Thanks so much, glad the content is helpful!
Thanks for explaining this so well. Cleared the 'fstring brain fog' I was in!
Glad it helped!
format() is useful in formatting string variables, which can't be done with f-strings. In some cases, I store frequently-used strings in my code as constant to prevent hard-coding. I use format() to format variables into the string constant.
for example:
STRING = "Hello, {}"
print(STRING.format("Sara"))
output:
Hello, Sara
Weird, but thanks for the example. Could come in handy.
It's backwards to how I always use format(), which is an interesting way to think about it.
Yep, same. For really big string templates I'll even use the jinja template generator on rare occasion.
Great tips, Arjan. Thanks!
Thanks Fabio, happy you’re enjoying the content!
If I remember it correctly str_format will be outperforming any other formatting once there are a lot of variables called. I believe in Python 3.9 that would have been a string printing out 13 different variables.
For me this would be a very artificial case, but also the one aspect which speaks in favour of str_format.
Also all the lovely features of f-strings were covered, which delights me. Good job on that :)
Very cool and useful tips, thanks Arjan!
Thanks so much Alex, glad the content is helpful!
Thanks for the video! I've found one niche use case for the old `format` method, which was in dynamic configurations. If I want the user to be able to specify a string (such as a filename), they can specify it as "file-{}-23", say, and various dynamic metadata will then be inserted into the filename using the `format` method.
f-strings cannot be used for creating templates. The code bellow would throw a NameError as 'number' is not defined. However it works with .formating.
template = "my number is {number}"
for i in range(5):
print(template.format(number=i)
Many Thanks, veryyyyyy useful 👍
Hi Arjan, been watching (and subbed) since you only had less than 5k subscribers. Congrats on hitting 100k! The little roof is called a caret in English.
Thanks Matthew.
Ive followed quite a lot of your content enjoy your enthusiasm and knowledgeable videos.
Thanks so much Jace, glad the content is helpful!
I had to look it up: the 'little roof' is called a caret in programming
I was going say, yes, ^ tends to get called 'caret' in English, at least in my experience here in the UK. Sometimes we might say 'circumflex', referring more to when it is a diacritic, especially in French (which is where I think many English speakers tend to meet it first)
aka 'hat' - now I want to know what the actual Dutch is.
thank you so much, saved me a lot of work!
Thanks so much, glad the content is helpful!
Thank you, Arjan. I 've been using f strings since they came out and i still learned a thing or two.
Thanks so much, glad you liked it!
Another gem from a great teacher ! 👌🏻👌🏻👌🏻👌🏻👌🏻
Thanks so much, glad the content is helpful!
Thanks! Learned a lot.
Thanks so much Alireza, glad the content is helpful!
Love the debugging tip!
Thanks so much, glad you liked it!
I really enjoy learning from your approaches with python programming.
Thanks so much Bo, glad the content is helpful!
Great video, really helpful!
Thanks so much Kevin, glad the content is helpful!
Great stuff thank you Arjan
Thanks so much Ste, glad you liked it!
That debugging feature with the equal sign at 19:31 is going to save me time, thank you!
I did not know we could apply Datetime in f-strings. Even math and assignment expressions! Awesome stuff.
Pendulum looks interesting, Arrow comes to mind too.
Is this debugging feature available in 3.6.8? I hit syntax issues in 3.6.8 when I try this
@@muthvar1 I found this in other comment: " f-string debugging version is valid from v3.8".
^ is called a "caret" or a "hat" if on top of a character, in English.
Thanks for the great videos
Excellent. There are lot of doubts cleared on "f-string" formatting.
Thanks so much Rahul, glad the content is helpful!
Thanks Arjan for making this video (and all your videos). You are terrific at teaching. Please make the video on Pendulum if you have an opportunity.
Thanks for the suggestions, Jeffrey, I've put it on the list.
I'm a big fan of Arjan's videos because he is a strong proponent of simple and easy-to-read code. I wish we had a couple of Arjan clones at my company 😀
Thanks so much, glad you liked the video and the content is helpful!
Hi Arjan, again a very nice and complete video. Great! I do have one question: I love f-strings but in loggers I seem only to be able to use % for lazy evaluation. Loggers do support {} bu that only seems to be possible in the specification of the log-message. So, question: can I use f-string style {} for lazy evaluation of log messages?
@Arjan: love the f-strings. As you mentioned they were introduced in v3.6. However the f-string debugging version is valid from v3.8. My tox test were failing with 3.7. That is how I discovered. The reason why developers don’t use the new formatting is not to break backwards compatibility.
Hey Arjan. Thanks for the content. I'd love a Better Time video if this fits in your schedule! Cheers and happy weekend.
Thanks so much, glad the content is helpful!
Thank you very much for the content and valuable lesson. I'd really like to learn more about pendulum, will you create a class about it as well?
Thanks for the suggestions, Renato, I've put it on the list.
4:00 Number literals ignore underscores*, so it's common to use f"(44_000_000_000:,.2}" instead of counting zeros.
* things like 1_23_4.56_7 are allowed (if ugly), but leading and trailing underscores are forbidden from both sides of the decimal point, so _100, 3.14_, 9_.8, and 2._6 all throw Syntax Error
Easier to just use 44e9 as a float, then convert to int as you need to 🤷♂️
As always, this video is great
Thanks Unique, happy you’re enjoying the content!
Really useful!
Thank you Rami, glad you liked the video!
Particularly liked the multi-line use. 👍👏
Thanks so much David.
Yes, do a video on pendulum please.
Quite informative👌
Thanks ✌️
damn, your videos are so great. I like them a lot. Thanks for your time
Thanks so much, glad the content is helpful!
Hey Arjan, Great video here, there were actually many things here that I didn't know about f-strings. I would like to ask, do you have any plans of making videos on the mypy package? I am trying to get into the habit of using types in my code and its working great especially when used on my own code. The issue I run into is when interfacing with external packages and sometimes their functions have wacky types on their parameters or failing to narrow the type of a variable so that mypy knows that after a specific check a variable is only of a certain type.
I feel that these are things that I don't really see covered in other mypy videos and wanted to see if maybe you would.
20:30 you can also use the multiline strings with fstring formatting, same as usual (3 quotes at beginning and end, with f before):
sentence = f"""some
multiline
text"""
This is a 1337 f string video.. Hat or Caret we call your little roof.. Keep up the great content..
Also something not mentioned in video is if you want to use an integer for the number of decimal places you need to use nested f-string formatting to achieve this.
Finally, a new class. Mind doing a video on reflection in python and how it works?
Thanks for the suggestions, Chris, I've put it on the list.
ooh, this'll allow me to tweak some of the printing options that I haven't touched from my supervisor's code (apart from moving them). he and I don't have the same programming backgrounds, so while it's a bit too strong to say that we "disagree" ... we often don't do things in the same way.
Great tutorial
Thanks Mehdi, happy you’re enjoying the content!
Dziękujemy.
Thank you so much Dawid!
great video as usual, anytime frame for the next discount on your course?
I read that repr should always return a string that, when pasted on the python interpreter, allows you to create an exact copy of the object
The __repr__ method should also return a unique string for each object, even when they have the same value. That's why the memory address is included in the output of the default __repr__ method.
I have been using interpolated strings in C# since I discovered them.
They are nice in python, too!
I wish there was interpolated strings in C or C++, though!
Great video, as always. One possible drawback of f-strings: can't use the /n character for multiline print if I'm not mistaken.
Great video. The only thing you missed that I use all of the time is the triple quote multi line string. Using that you can use single and double quotes in your string to access dicts. Glad you skipped the most newbie form of string generation the evil and slow + operator. I saw a cheat sheet for python and it showed that, I thought whomever wrote that cheat sheet mustn't have used python much. I use and peach the use of f strings for all the reasons you mentioned. So readable and obvious.
Ah, I didn't see your comment before I replied with the same thing 😅
wow, what a great QOL update.
I've been still using the function, which would always end up looking like .format(name=name, age=age, screw=this). Which hurts my heart.
This new way uses all the same operators that I am used to, so easy and much appreciated change.
Thanks so much, glad the content is helpful!
Thanks for the breakdown of performance that is interesting!
What did you mean when you said this feature is called debugging? Is that the f string term? I don’t think of printing variables as debugging.
I was looking into jinja templates for creating some text config files but not sure how it will go compared to doing it with python loops and f strings. I wonder if f strings could ever get more functionality.
Hello. Great video. Big help. ^ in english is a caret 😊
What I learned today. We can all be 'leet' twice per day.
But, seriously, another good instructional video.
Formatted strings are left-aligned by default so the extra spaces in f"{greet:6}" appear on the right (i.e., "Hi "). The ">" switches this to right-aligned (which is the default for numbers).
Other formatting methods should be used in order for beginners to understand why f-strings are so awesome. Nice one again, Arjan!
It's still useful to learn them as long as there is so much legacy code floating around on the web.
@@MattRose30000 you are completely right. As a matter of fact, the percentage style formatting is very much a common feature of many langs. Talking about legacy code, what's up with the new Int to Str conversion in python? It broke lots of libraries!
Arjan, I love f-strings, dataclasses and other things that you show up. Unfortunately, where I work, people are still clinging to older versions of python... all the way back to 2.7... how do you convince people to migrate from 2.7 to 3.8 or later?
nice, didn't knew these.
Thanks so much, glad the content is helpful! :)
Great video as usual. Small nit, tho: using single quotes within f-strings isn't the only way to access quoted values like dict's.
You can also use triple quotes. It's noisier, but you can 😉
`print("""Like so: { dictionary["key"] }""")`
Ha, good point!
Is it possible to use dynamic formatting in F-strings? Like, when you have a user definable number of decimals to show. In percentage formatting I would create the format string like "%%.%df" % (no_digits)
I have been using f-strings for almost everything except
(1) Dynamic formatting. Declare an unformatted string such that it can later be used in multiple places, replaced with different variables.
(2) LaTeX or any script that involves a lot of curly brackets, "{" and "}". While it is possible to escape curly brackets in f-strings, I would prefer to keep my script concise.
cool, I didn't know some of these.
And about the others form of string formatting, I use them if it is for templates if I use it multiples times and then just call .format on it, otherwise f-string for the win, and now when I check my old code I always change the old formats to f-string...
I still use .format() when I need cariage return or tab in my string ("/n","/t"). How do you manage to use that kind of special caracter with f-string? (I use f"{chr(10)}" but I think it is harder to read than "/n")
I LOVE f-strings and I use them constantly, but I still managed to learn a few things from this video! I didn’t know f-strings could do time formatting and I didn’t know that the debugging f-strings would honor spaces.
The only thing f-strings is missing is lazily evaluated or deferred f-strings. That’s the only reason I ever use format() or Template. It’d be nice to be able to pass lazy f-strings to functions or load them from configs.
You can build an f-string using normal string methods, compile it using the compile function, and invoke the compiled version using eval(code, 'generated', 'eval'). It will run surprisingly fast.
@@davidagnew8465 Yeah, but using eval() seems pretty hackish and problematic, especially when you're dealing with strings that have quotes in them. It could become a nightmare to escape properly and eval has negative security implications. I avoid using it wherever possible, doubly so if any variables contain user input.
What would be nice is if we had a way to tell python that an f-string was lazy when we defined it. Then it would evaluate when __str__ dunder is called. Something like putting f! instead of f:
>>> template = f!"Number: {i:2}"
>>> for i in range(8,11):
2 print(template)
Number: 8
Number: 9
Number: 10
@Jonathan Maybe a function is more appropriate for this kind of cases?
template = lambda i: f"Number: {i:2}"
for i in range(8,11):
print(template(i))
def my_big_template(name, amount, currency):
return f"{name} has deposited {amount:.2}{currency}"
for name, amount in zip(people, deposits):
print(template(name, amount, "$"))
What are best practices for using f-strings with internationalization?
Hi Arjan, what do you think about the pylint warning W1203 "Use %s formatting in logging functions" raised if f-strings are used log messages? As far as I understand it's to avoid the formatting operation if the log message is usually not shown (e.g. debug messages at info-level) and come corner cases where f-string might cause an exception.
also for log seggregation.
can the format be parametric? e.g. setting digits=4 and doing something like print(f"{123.345567:.digits}") ?
At the start you showed how to print 800 as a hex number but it didn't look like 0x320. Is that possible with an f-string option?
Thanks
You're Welcome!! :)
Very nice! (and I thought I knew f-strings). By the way I oftern use the debugging feature with embedded calculations like so: f"{quantity * price = }". Very handy at times.
There needs to be a "cheat sheet" showing all these options. (Is there?)
Is there a sum up to all the subjects in the video? plz
Is f-strings faster even if you don't actually print a variable? E.g. print(f"Hello World") vs print ("Hello World")?
The only thing I haven't been able to figure out how to do with f-strings that you can do with .format is how to expand a dictionary into the placeholders.
i.e. don't think you can do this:
```
template = "my number is {number} {item}"
values = dict(number=1, item='box')
print(template.format(**values))
```
Output: _my number is 1 box_
That's a good reason indeed to still use templates. You could also do this, but templates might still be easier:
```
FRUITS = [{"name": "Arjan", "fruit": "apples"}, {"name": "Paula", "fruit": "grapes"}]
for obj in FRUITS:
name, fruit = obj.values()
print(f"{name} likes {fruit}.")
```
My one and only format() use case is dynamically inserting variables into a large SQL query (in my case, large multi-line strings, perhaps 50 lines on average).
In this case it would be safer to use the cursor execute method with parameters to prevent SQL injection.
@@alexanderpoplawski577 Interesting! I hadn't thought to do that, but that's a great idea
pylint complains at me when I use f-strings when passing a message to the logging module. Pylint(W1203:logging-fstring-interpolation)
Is this warning bogus?
Hello pls can you provide a list of best python GUI frameworks? Thank you
Nice contents! I am also working in the Netherlands, and I found our Dutch computers expect “.” as the thousands separator and “,” as the decimal separator. Is there a quick way to print numbers in such a format?
f"{str(your_variable).replace('.',',')} possibly?
@@stevegrimes5105 it is basically what I am doing now, by swapping the symbols. But I hope there is a more elegant, robust and flexible solution. Thanks bro!
Glad you've covered f-strings. Can't wait until the g-string video comes out. ;)
That will unfortunately only be available on my OnlyFans.
@@ArjanCodes Haha. Can't wait! Don't forget the "1337" medallion!
I'm sure he can pull it off.
Would love a pendulum tutorial.
Thanks for the suggestions, I've put it on the list.
@@ArjanCodes Thank you!
Maybe a little bit out of context :) but when I get a date info from an email using imaplib and email, it always come as utc. Can I change the timezone info and get the date as I intend to my own timezone or should I use f-string way or just manipulate the date object with timedelta(hours)?
Thanks for all the efforts, it's been a joy to watch your videos so far :) (sorry for the English if I made some mistakes)
It's better to do with pytz rather than timedelta:
import pytz
localized_datetime = pytz.timezone(timezone).localize(datetime.datetime())
the list of available timezones you can find in pytz/__init__.py file
@@SoWhatsAgain I will try that, thank you for the answer.
I use f-strings for everything except If something has to be translated. Most of the projects I am working on are using pyqt and translation is done via qt linguist.
4:10 is it possible to use f strings to change:
"." as thousand separator and
"," as decimal separator?
thank you for sharing your knowledge Arjan!
that's my question as well
You can check out the built-in "locale" module for that.
try this:
```
import locale
val = 1_000_000
loc = locale.getlocale()
print(loc)
print(f'{val}')
print(f'{val:,}')
print(f'{val:,.02f}')
print(f'${val:,.02f}')
loc = locale.setlocale(locale.LC_ALL, 'de_DE')
print(loc)
print(f'{val}')
print(f'{val:,}')
print(f'{val:,.02f}')
print(f'${val:,.02f}')
```
i used some online ide and it failed because most of them have only us_US installed.
if you are on linux you can check what locale you have installed with the following command:
```
➜ locale -a
C
C.UTF-8
en_US.utf8
POSIX
➜
```
these are the one installed on the online ide that i've used.
there is probably also a way to display with locale the currency without hardcoded currency symbol; euros for germany
I use this way: print(f"The number is {8000:_.2f}".replace(".",",").replace("_","."))
know what they tNice tutorialnk, and hopefully give so pointers. Thank you!
What I would like to know is, why are f-strings faster than the are formatting types?