Unmatched python ошибка

How to fix SyntaxError: unmatched ‘)’ error in python, in this scenario I forgot by mistakenly opening parentheses “(” that is why we face this error in python. This is one of the command errors in python, especially in our beginning stage if face this type of error just find where you miss opening parentheses “(“ just enter then our code error free see the below code.

Wrong Code

# Just create age input variable
a = input("What is YOur Current age?n")

Y = 101 - int(a)
M = Y * 12
W = M * 4
D = W * 7
print(f"You have {D} Days {W} Weeks, {M} Months And {Y} Years Left In Your Life")
print"Hello World")

Error Massage

  File "/home/kali/python/webproject/error/main.py", line 11
    print"Hello World")
                      ^
SyntaxError: unmatched ')'

Wrong code line

print"Hello World")

Correct code line

print("Hello World")

Entire Correct Code line

# Just create age input variable
a = input("What is YOur Current age?n")

Y = 101 - int(a)
M = Y * 12
W = M * 4
D = W * 7
print(f"You have {D} Days {W} Weeks, {M} Months And {Y} Years Left In Your Life")
print("Hello World")

What is SyntaxError: unmatched ‘)’ In Python?

Syntax in python sets forth a specific symbol for coding elements like opening and closing parentheses (), Whenever we miss the opening that time we face SyntaxError: unmatched ‘)’ In Python. See the above example.

How to Fix SyntaxError: unmatched ‘)’ In Python?

Syntax in python sets forth a specific symbol for coding elements like opening and closing parentheses (), Whenever we miss the opening that time we face SyntaxError: unmatched ‘)’ so we need to find in which line of code we miss special opening “(“symbol and need to enter correct symbols, See the above example.

For more information visit Amol Blog Code YouTube Channel.

To fix the SyntaxError: f-string: unmatched ‘(‘ in Python, you need to pay attention to use single or double quotes in f-string. You can change it or not use it. Please read the following article for details. 

New built-in string formatting method from Python 3.6 in the following syntax:

f''a{value:pattern}b''

Parameters:

  • f character: use the string f to format the string.
  • a,b: characters to format.
  • {value:pattern}: string elements need to be formatted.
  • pattern: string format.

In simple terms, we format a string in Python by writing the letter f or F in front of the string and then assigning a replacement value to the replacement field. We then transform the replacement value assigned to match the format in the replace field and complete the process.

The SyntaxError: f-string: unmatched ‘(‘ in Python happens because you use unreasonable single or double quotes in f-string.

Example: 

testStr = 'visit learnshareit website'

# Put variable name with the string in double quotes in f-string for formatting
newStr = f"{(testStr + "hello")}"
print(newStr)

Output:

  File "code.py", line 4
    newStr = f"{(testStr + "hello")}"
                            ^
SyntaxError: invalid syntax

How to solve this error?

Change the quotes

The simplest way is to change the quotes. If your f-string contains double quotes, put the string inside it with single quotes.

Example:

testStr = 'visit learnshareit website'

# Use single quotes for strings in f-string when f-string contains double quotes
newStr = f"{(testStr + ' hello')}"
print(newStr)

Output:

visit learnshareit website hello

Similarly, we will do the opposite if the f-string carries single quotes. The string in it must carry double quotes.

Example:

testStr = 'visit learnshareit website'

# f-string contains single quotes. The string must contain double quotes
newStr = f'{(testStr + " hello")}'
print(newStr)

Output:

visit learnshareit website hello

Do not use single or double quotes

If the problem is with quotes confusing you, limit their use inside the f-string.

Example:

  • I want to concatenate two strings instead of using quotes inside the f-string. Then I declare 2 variables containing two strings and use the addition operator to concatenate two strings inside f-string so that will avoid SyntaxError: f- string: unmatched ‘(‘.
testStr = 'visit learnshareit website'
secondStr = '!!!'

newStr = f'{ testStr + secondStr }'
print(newStr)

Output:

visit learnshareit website!!!

Summary

The SyntaxError: f-string: unmatched ‘(‘ in Python has been resolved. You can use one of two methods above for this problem. If there are better ways, please leave a comment. We appreciate this. Thank you for reading!

Maybe you are interested:

  • How To Resolve SyntaxError: ‘Break’ Outside Loop In Python
  • How To Resolve SyntaxError: f-string: Empty Expression Not Allowed In Python
  • How To Resolve SyntaxError: F-string Expression Part Cannot Include A Backslash In Python

Jason Wilson

My name is Jason Wilson, you can call me Jason. My major is information technology, and I am proficient in C++, Python, and Java. I hope my writings are useful to you while you study programming languages.


Name of the university: HHAU
Major: IT
Programming Languages: C++, Python, Java

The f strings are commonly used for better formatting Python strings. Also referred to as Formatted string literals, f strings are widely used for formatting. However, one may encounter an error that is majorly syntactical while working on f strings. Review this blog to learn more about the ‘f string unmatched’ error.

What are f strings in Python?

Python has a f string type, which is a formatted string literal. A formatted string literal is just what it sounds like. It’s a string that you can format using special characters, such as the percent sign (%) and the ampersand (&), to create formatting rules.

These strings contain both the actual text and formatting information, such as fonts or so that your program can render correctly and then print out by the computer. This is useful for things like printing out data from databases or from other programs, so you can see how it will look when it’s outputted.

How do format strings/plain text?

You can utilize format text in two ways: literals or formatting expressions.

A literal is a text inside your program; an expression is any piece of code that produces some value or action. In this case, we’ll focus on formatting expressions since they’re more common than literals (but both will work).

To format text using Python, you must use either the str() function or the built-in repr() function. The str() function returns a formatted string object. This object is also known as FPM. It contains all of the information about how your text should be displayed when printed out.

Why you got the f string unmatched error?

This might have happened when the quotes used with f strings don’t match. For example, if you have used double quotes with double quotes in your string or single quotes with single quotes, this error is likely to occur.

Resolution of error

Normally, the f string should have either double or single quotes along with the other quotes type. For example, it can be either double quotes with a single quote or a single with a double quote. In case you mix them, it will result in f string unmatched error.

f"hello ' correct"
#or
f'hello " correct'

On the other hand, if it is a double with a double quote or a single quote with a single quote, you will get the error. Hence, check for the quotes.

f"hello " wrong "
#or
f'hello ' wrong'
# will give error.

Hence, wrapping the text in the opposite quotes type will make the code error-free. Let us observe another example to get a better view of the resolution of the error.

game = 'chess'
print(f"GAME: {game.replace('chess', 'ludo')}")

They are easier to read and use. Infact, they’re similar to printf() functions in other languages, but they come with many advantages say they can be used as a replacement for print() in your code. Also, they can be easily parsed by the Python interpreter.

Besides this, a few extra features including custom format specifiers and inserting newlines into output are also available with f strings. So they are of great use to anyone who’s coding in Python.

f strings with triple quotes

In case you have used double and single quotes, you may use triple quotes.

game = 'chess'
print(f"""games: {game.replace("chess", "ludo")}""")

You may check this article too: How to Remove Quotes From a String in Python(Opens in a new browser tab)

f strings with correct braces

Wherever you require the string to be formatted, use a curly brace instead of any other type of braces.

lang = 'python'
print(f'language: {lang}')  

And the output will be:

f strings with square brackets

Square brackets work when we are accessing dictionary items using f strings.

website = {'site': 'pythonpool'}
print(f"site_a: {website['site']}")

f strings with backslash

Python doesn’t allow a user to use backslash directly with the format string. So in case you wish to apply backslash in a statement, store that backslash in a variable and use f string formatting with the variable.

Input = ord('n')
print(f"newline: {Input}")
#this backslash works now as f string #formatting is used with the variable only.

f strings with decimal values

You may try using f string formatting with decimal notation values. You need to specify the precision value also. It means how many digits you want after the decimal. It uses this syntax:

f'{value:{width}.{precision}'

For example, look at this code:

No = 550.9999
print(f'{No:.2f}')
#will result in '550.99'

Advantages of using f strings over other formatting options

Python’s f strings are a shorthand for calling the format() function. They’re useful for writing short functions that wrap up formatting in one line of code. The advantage of f strings is that they use the same syntax as other methods and functions, which means you can take advantage of all the built-in tools in the language.

In addition to being shorter than your regular function calls, they also have a few other advantages. They don’t require any arguments (unlike format()). They don’t require any whitespace after the method name (unlike format()) and they work on both Python 2 and 3 (unlike format()).

f strings or format strings?

F strings can be used in place of format strings where the string representation isn’t important. The main difference between them is that f string supports unicode strings whereas format function only works with text.

Format strings require additional logic to get text out of a variable or object, while f string only requires an integer index (as long as the variable or object has an ordinal).

This means that you can use unicode characters in your f strings and they’ll work just like normal strings. This can be useful when working with internationalized data or sending text messages over the internet.

You should also consider using f string if you want to add some flexibility to your string formatting, since it allows you to add more options for how your string will display.You can use the + operator to combine two or more formatting options together into one string, which makes writing complex formatting logic easier than using the format function alone.

FAQs

What is a prerequisite for working with f strings?

Make sure that you have stated the f symbol while specifying the f string.

Conclusion

This article resolved the ‘f string unmatched error’ and discussed ways to prevent it. In this tutorial, we also learned how to use Python’s f string type using the str.format() function.

Trending Python Articles

  • [Solved] typeerror: unsupported format string passed to list.__format__

    [Solved] typeerror: unsupported format string passed to list.__format__

    May 31, 2023

  • Solving ‘Remote End Closed Connection’ in Python!

    Solving ‘Remote End Closed Connection’ in Python!

    by Namrata GulatiMay 31, 2023

  • [Fixed] io.unsupportedoperation: not Writable in Python

    [Fixed] io.unsupportedoperation: not Writable in Python

    by Namrata GulatiMay 31, 2023

  • [Fixing] Invalid ISOformat Strings in Python!

    [Fixing] Invalid ISOformat Strings in Python!

    by Namrata GulatiMay 31, 2023

Created on 2021-09-02 14:55 by Greg Kuhn, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (9)
msg400920 — (view) Author: Greg Kuhn (Greg Kuhn) Date: 2021-09-02 14:55
Hi All, 
Is the below a bug? Shouldn't the interpreter be complaining about a curly brace?

$ python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> f'[{num]'
  File "<stdin>", line 1
SyntaxError: f-string: unmatched ']'
>>>
msg400925 — (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-09-02 15:29
I think the error is short for "I found a ']' without a matching '['".
msg400930 — (view) Author: Greg Kuhn (Greg Kuhn) Date: 2021-09-02 15:45
But doesn't the square bracket have no relevance here?
It's not within a curly bracketed string so shouldn't be treated specially.

I would have expected the error to be: SyntaxError: f-string: unmatched '}'.

Unless I need to go back and reread pep498...
msg400942 — (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-09-02 17:17
I think it's basically this error:

>>> num]
  File "<stdin>", line 1
    num]
       ^
SyntaxError: unmatched ']'

Although I'd have to look at it more to see why that's the error it chose to display, instead of the curly brace.
msg401029 — (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2021-09-04 02:06
The behavior remains the same in 3.11 ('main' branch).  New PEG parser parses this the same.

(Pablo, if there is a mistake below, please correct.)

Normally, the parser copies code chars between quotes, with or without '' interpretation, into a string object.  When the 'f' prefix is given, the string gets divided into substrings and replacement fields.  The code part of each replacement field is separately parsed.  There are two options: 1. parse the field code while looking for an endcode marker; 2. look ahead for an endcode marker and then parse the code.

The current behavior is consistent with opotion 1 and the python policy of reporting the first error found and exiting, rather than trying to resynchronize to try to find more errors.
msg401034 — (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2021-09-04 02:58
I don't think it really makes a difference, but here's some background:

For f-strings, the parser itself does not break apart the f-string into (<text>, <expression>) parts. There's a custom parser (at https://github.com/python/cpython/blob/0b58e863df9970b290a4de90c67f9ac30c443817/Parser/string_parser.c#L837) which does that. Then the normal parser is used to parse the expression portion.

I think the error shown here is not in the expression parser, but in the fstring parser in fstring_find_expr(), at https://github.com/python/cpython/blob/0b58e863df9970b290a4de90c67f9ac30c443817/Parser/string_parser.c#L665

As Terry says, it's not incorrect to print the error show in this bug report.

To further diverge:

There's been talk about using the normal parser to pull apart the entire f-string, instead of using the two-pass version I mention above. But we've never gotten past just talking about it. There are pros and cons for doing it with the normal parser, but that's a discussion for a different forum.
msg401042 — (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-09-04 12:29
> But we've never gotten past just talking about it

Stay tuned! :)

 https://github.com/we-like-parsers/cpython/tree/fstring-grammar
msg401046 — (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2021-09-04 16:38
Thank you Eric.  I can see now that the actual process is a somewhat complicated mix of the simple options 1 and 2 I imagined above.  It is like option 2, except that everything between '{' and '}' is partially parsed enough to create a format object.  This is required to ignore quoted braces

>>> f'{"}"'
SyntaxError: f-string: expecting '}'

and detect valid '!' and ':' markers.  In that partial parsing, unmatched fences are detected and reported, while other syntax errors are not.  If my option 1 above were true, the first example below would instead report the 'a a' error.

>>> f'{a a'
SyntaxError: f-string: expecting '}'
>>> f'{a a]'
SyntaxError: f-string: unmatched ']'
>>> f'{a a}'
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

The second plausibly could, but outside of the f-string context, the error is the same.
>>> a a]
SyntaxError: unmatched ']'
 
Greg, the fuller answer to your question is that the interpreter is only *required* to report that there is an error and some indication of where.  "SyntaxError: invalid syntax" is the default.  It may have once been all that was ever reported.

A lot of recent effort has gone into adding detail into what is wrong and what the fix might be.  But both additions sometimes involve choices that may not meet a particular person's expectation.  Another person, expecting linear rather than nested parsing, might look at the first example above and ask whether the interpreter should be complaining about the 'a a' syntax error instead of the following lack of '}' f-string error.  And I would not call it a bug if it were to do so in the future.
msg401048 — (view) Author: Greg Kuhn (Greg Kuhn) Date: 2021-09-04 17:35
I see, thank you all for the detailed investigation and explanation!!

Agreed Terry, anyone who reads the error should be able to parse it themselves and see what the errors is. Pointing the user to the error site is the most important piece.
History
Date User Action Args
2022-04-11 14:59:49 admin set github: 89249
2021-09-04 17:35:20 Greg Kuhn set messages:
+ msg401048
2021-09-04 16:38:49 terry.reedy set messages:
+ msg401046
2021-09-04 12:29:38 pablogsal set messages:
+ msg401042
2021-09-04 02:58:34 eric.smith set messages:
+ msg401034
2021-09-04 02:07:00 terry.reedy set status: open -> closed

versions:
+ Python 3.9, Python 3.10, Python 3.11
nosy:
+ pablogsal, terry.reedy

messages:
+ msg401029
resolution: not a bug
stage: resolved

2021-09-02 17:17:34 eric.smith set messages:
+ msg400942
2021-09-02 15:45:59 Greg Kuhn set messages:
+ msg400930
2021-09-02 15:29:06 eric.smith set nosy:
+ eric.smith
messages:
+ msg400925
2021-09-02 14:55:20 Greg Kuhn create

I’m trying to use f-strings in python to substitute some variables into a string that I’m printing, and I’m getting a syntax error.
Here’s my code:

print(f"{index+1}. {value[-1].replace("[Gmail]/", '')}")

I only started having the problem after I added the replace. I’ve checked plenty of times and I’m certain that I’m not missing a parenthesis. I know that there are plenty of other ways to accomplish this, some of which are probably better, but I’m curious why this doesn’t work.

smci's user avatar

smci

32.1k19 gold badges113 silver badges146 bronze badges

asked May 14, 2021 at 20:07

Cameron Delong's user avatar

Cameron DelongCameron Delong

4141 gold badge6 silver badges12 bronze badges

3

Your problem is double quotes inside double quotes.
For example,

  • OK —> f"hello ' this is good"
  • OK —> f'hello " this is good'
  • ERROR —> f"hello " this breaks"
  • ERROR —> f'hello ' this breaks'

This one should work correctly:

print(f"{index+1}. {value[-1].replace('[Gmail]/', '')}")

Out of scope but still I do not advise you to use replace inside f-string. I think that it would be better to move it to a temp variable.

Seymour's user avatar

Seymour

3,0262 gold badges21 silver badges45 bronze badges

answered May 14, 2021 at 20:11

Oleksandr Dashkov's user avatar

I had the same issue,change all the double quote within the parenthesis to single quotes.It should work
eg from
print( f» Water : {resources[«water»] } » )
to
print( f» Water : {resources[‘water’] } » )

answered Mar 28, 2022 at 10:16

user17597998's user avatar

1

Seems like this does not work

x = 'hellothere'
print(f"replace {x.replace("hello",'')}")

error

    print(f"replace {x.replace("hello",'')}")
                                ^
SyntaxError: f-string: unmatched '('

Try this instead

x = 'hellothere'
print(f"replace {x.replace('hello','')}")

single quotes 'hello'
output is

replace there

answered May 14, 2021 at 20:11

Thavas Antonio's user avatar

Thavas AntonioThavas Antonio

5,7891 gold badge13 silver badges42 bronze badges

Another way to do some string formatting (which in my opinion improves readability) :

print("{0}. {1}".format(index+1, 
                        value[-1].replace("[Gmail]/", "")))

answered May 14, 2021 at 20:11

Charles Dupont's user avatar

Вот код

import requests
from bs4 import BeautifulSoup

def get_first_market_steam():
	  headers = {
	    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
	    'cookie': '_ym_d=1617117545; _ym_uid=161711754528794970; G_ENABLED_IDPS=google; xf_logged_in=1; xf_user=2306008%2C8db46d26a5f78cb04ad8cebd5a7ee6c592170111; timezoneOffset=10800,0; _ga=GA1.1.1292113123.1617117545; xf_last_read_article_date=1617636960; df_id=4edaa88206ca95ffd4e5b6cf693c3d6c; xf_session=eea6a8e176357d0083c7a3df97b42e27; xf_market_items_viewed=14961375%2C15963732%2C15978709%2C15573578%2C15807316; xf_market_search_url=%2Fmarket%2F; _ga_J7RS527GFK=GS1.1.1625692903.224.1.1625702146.0'
	  }

	  url = 'https://lolz.guru/market/steam/'
	  r = requests.get(url=url, headers=headers)

	  soup = BeautifulSoup(r.text, 'lxml')
	  markets_cards = soup.find_all('div', class_='marketIndexItem')
	  print(market_cards)

	  for market in markets_cards:
	  	  market_title = soup.find('a', class_='marketIndexItem--Title').text.strip()
	  	  market_info = soup.find('div', class_='marketIndexItem--Badges stats').text.strip()
	  	  market_infogame = soup.find('div', class_='marketIndexItem--Badges').text.strip()
	  	  market_infouser = soup.find('div', class_='marketIndexItem--otherInfo').text.strip()
	  	  market_url = f'https://lolz.guru/{market.get('href')}'


	  	  print (f'{market_title} | {market_info} | {market_infogame} | {market_infouser} | {market_url}')


get_first_market_steam()

Вот ошибка

line 22
    market_url = f'https://lolz.guru/{market.get('href')}'
                                                  ^
SyntaxError: f-string: unmatched '('

Пытался найти в гугле не нашел

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Closed

GregKuhn mannequin opened this issue

Sep 2, 2021

· 9 comments

Closed

f-string unmatched ‘]’

#89249

GregKuhn mannequin opened this issue

Sep 2, 2021

· 9 comments

Labels

3.8

only security fixes

3.9

only security fixes

3.10

only security fixes

3.11

bug and security fixes

type-bug

An unexpected behavior, bug, or error

Comments

@GregKuhn

BPO 45086
Nosy @terryjreedy, @ericvsmith, @pablogsal

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2021-09-04.02:07:00.047>
created_at = <Date 2021-09-02.14:55:20.162>
labels = ['type-bug', '3.8', '3.9', '3.10', '3.11', 'invalid']
title = "f-string unmatched ']'"
updated_at = <Date 2021-09-04.17:35:20.547>
user = 'https://bugs.python.org/GregKuhn'

bugs.python.org fields:

activity = <Date 2021-09-04.17:35:20.547>
actor = 'Greg Kuhn'
assignee = 'none'
closed = True
closed_date = <Date 2021-09-04.02:07:00.047>
closer = 'terry.reedy'
components = []
creation = <Date 2021-09-02.14:55:20.162>
creator = 'Greg Kuhn'
dependencies = []
files = []
hgrepos = []
issue_num = 45086
keywords = []
message_count = 9.0
messages = ['400920', '400925', '400930', '400942', '401029', '401034', '401042', '401046', '401048']
nosy_count = 4.0
nosy_names = ['terry.reedy', 'eric.smith', 'pablogsal', 'Greg Kuhn']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue45086'
versions = ['Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11']

@GregKuhn



Copy link


Mannequin


Author

Hi All,
Is the below a bug? Shouldn’t the interpreter be complaining about a curly brace?

$ python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> f'[{num]'
  File "<stdin>", line 1
SyntaxError: f-string: unmatched ']'
>>>

@GregKuhn
GregKuhn
mannequin

added

3.8

only security fixes

type-bug

An unexpected behavior, bug, or error

labels

Sep 2, 2021

@ericvsmith

I think the error is short for «I found a ‘]’ without a matching ‘[‘».

@GregKuhn



Copy link


Mannequin


Author

But doesn’t the square bracket have no relevance here?
It’s not within a curly bracketed string so shouldn’t be treated specially.

I would have expected the error to be: SyntaxError: f-string: unmatched ‘}’.

Unless I need to go back and reread PEP-498…

@ericvsmith

I think it’s basically this error:

>>> num]
  File "<stdin>", line 1
    num]
       ^
SyntaxError: unmatched ']'

Although I’d have to look at it more to see why that’s the error it chose to display, instead of the curly brace.

@terryjreedy

The behavior remains the same in 3.11 (‘main’ branch). New PEG parser parses this the same.

(Pablo, if there is a mistake below, please correct.)

Normally, the parser copies code chars between quotes, with or without » interpretation, into a string object. When the ‘f’ prefix is given, the string gets divided into substrings and replacement fields. The code part of each replacement field is separately parsed. There are two options: 1. parse the field code while looking for an endcode marker; 2. look ahead for an endcode marker and then parse the code.

The current behavior is consistent with opotion 1 and the python policy of reporting the first error found and exiting, rather than trying to resynchronize to try to find more errors.

@ericvsmith

I don’t think it really makes a difference, but here’s some background:

For f-strings, the parser itself does not break apart the f-string into (<text>, <expression>) parts. There’s a custom parser (at

fstring_find_literal_and_expr(Parser *p, const char **str, const char *end, int raw,

) which does that. Then the normal parser is used to parse the expression portion.

I think the error shown here is not in the expression parser, but in the fstring parser in fstring_find_expr(), at

As Terry says, it’s not incorrect to print the error show in this bug report.

To further diverge:

There’s been talk about using the normal parser to pull apart the entire f-string, instead of using the two-pass version I mention above. But we’ve never gotten past just talking about it. There are pros and cons for doing it with the normal parser, but that’s a discussion for a different forum.

@pablogsal

@terryjreedy

Thank you Eric. I can see now that the actual process is a somewhat complicated mix of the simple options 1 and 2 I imagined above. It is like option 2, except that everything between ‘{‘ and ‘}’ is partially parsed enough to create a format object. This is required to ignore quoted braces

>>> f'{"}"'
SyntaxError: f-string: expecting '}'

and detect valid ‘!’ and ‘:’ markers. In that partial parsing, unmatched fences are detected and reported, while other syntax errors are not. If my option 1 above were true, the first example below would instead report the ‘a a’ error.

>>> f'{a a'
SyntaxError: f-string: expecting '}'
>>> f'{a a]'
SyntaxError: f-string: unmatched ']'
>>> f'{a a}'
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

The second plausibly could, but outside of the f-string context, the error is the same.
>>> a a]
SyntaxError: unmatched ']'
 
Greg, the fuller answer to your question is that the interpreter is only *required* to report that there is an error and some indication of where.  "SyntaxError: invalid syntax" is the default.  It may have once been all that was ever reported.

A lot of recent effort has gone into adding detail into what is wrong and what the fix might be. But both additions sometimes involve choices that may not meet a particular person’s expectation. Another person, expecting linear rather than nested parsing, might look at the first example above and ask whether the interpreter should be complaining about the ‘a a’ syntax error instead of the following lack of ‘}’ f-string error. And I would not call it a bug if it were to do so in the future.

@GregKuhn



Copy link


Mannequin


Author

I see, thank you all for the detailed investigation and explanation!!

Agreed Terry, anyone who reads the error should be able to parse it themselves and see what the errors is. Pointing the user to the error site is the most important piece.

Labels

3.8

only security fixes

3.9

only security fixes

3.10

only security fixes

3.11

bug and security fixes

type-bug

An unexpected behavior, bug, or error

На чтение 12 мин Просмотров 5.9к. Опубликовано 27.12.2021

Не смотря на один из принципов Python, гласящий: «Должен существовать один — и, желательно, только один – очевидный способ сделать что-то», в нашем любимом языке есть аж четыре способа отформатировать строку. Так сложилось исторически.
Это второй урок цикла, посвящённого форматированию строк. В него входят:

  1. Строковый оператор форматирования
  2. Метод format()
  3. f-Строки
  4. Шаблонные строки

В данном уроке мы познакомимся с f-Строками.
В Python 3.6 появился новый способ форматирования строки – интерполяция строк (чаще называют «форматированные строковые литералы» или «f-Строки»).
f-Строки предоставляют возможность использовать выражения Питона внутри строк. Происходит это следующим образом: каждое выражение вычисляется, затем все части f-Строки отдельно преобразуется в обычные строки, затем все части конкатенируются (склеиваются в одну). Форматированные строковые литералы так же, как и описанный в предыдущем уроке метод строки .format(), поддерживают форматирование, описанное в атрибуте __format__ . Узнать f-Строки Вы можете по символу «f» в начале строки перед открывающей кавычкой.

Содержание

  1. Простой синтаксис
  2. Произвольные выражения
  3. Многострочные F-Strings
  4. Скорость
  5. Python F-Строки: Детали
  6. Кавычки
  7. Словари
  8. Скобки
  9. Бэкслеши
  10. Междустрочные комментарии
  11. Форматирование вставляемых выражений

Простой синтаксис

Для того, чтобы использовать форматированные строковые литералы, просто поставьте символ «f» перед строкой и укажите в ней в фигурных скобках выражения Питона. В простейшем случае это имена переменных. Python, как всегда, радует своей лаконичностью! Пример:


язык = 'Python'
проценты = 100
print(f'-Самый лучший язык - {язык}.n'
    f'-Точно?n'
    f'-{проценты}%!')
# Вывод:
-Самый лучший язык - Python.
-Точно?
-100%!

Как видите, форматированные строковые литералы могут быть многострочными, но символ «f» должен быть в начале каждой строки.
Если Вы используете заглавную «F» — интерпретатор всё равно Вас поймёт:


print(F'2 + 2 = {2 + 2}')
# Вывод:
2 + 2 = 4

Надеюсь, Вы в таком же восторге от этого синтаксиса, как и я!

Произвольные выражения

Обратите внимание, в предыдущем примере мы использовали в строке выражение {2 + 2}. Оно сперва вычисляется, а затем преобразуется в строку. Это, конечно, открывает большие возможности.


my_var = input('Введи и я умножу ')

print(f'{(my_var + " ") * 2}')
# Вывод:
Введи и я умножу Hello!
Hello! Hello!

Также вы можете вызывать функции. Вот упрощённое решение задачи из урока про input():


первое_число = int(input('Введите число '))
первый_знак = input('Введите знак ')
второе_число = int(input('Введите число '))
второй_знак = input('Введите знак ')
третье_число = int(input('Введите число '))

def calculate(first_digit, operator, second_digit):
    if operator == '+':
        return first_digit + second_digit
    if operator == '-':
        return first_digit - second_digit
    if operator == '*':
        return first_digit * second_digit
    if operator == '/':
        try:
            return first_digit / second_digit
        except ZeroDivisionError:
            print('Делить на ноль нельзя - это опасно!')

print(f'{calculate(calculate(первое_число, первый_знак, второе_число), второй_знак, третье_число)}')
# Вывод:
Введите число 2
Введите знак +
Введите число 2
Введите знак /
Введите число 3
1.3333333333333333

Обратите внимание, это упрощённое решение. Здесь нет проверки на очерёдность выполнения арифметических действий, проверки на то, что введено цело число и т. д. Разработку этих деталей оставляю Вам для самостоятельной работы.
Также вы можете вызывать методы объектов:


my_var = input('Введи и я умножу ')

print(f'{(my_var + " ").split() * 2}')
# Вывод:
Введи и я разделю Hello!
['Hello!', 'Hello!']

Вы даже можете использовать объекты, созданные из классов при помощи f-строки.


class Foo:
    pass

print(f'{Foo()} is instance of {Foo}')
# Вывод:
<__main__.Foo object at 0x000002425BE70E50> is instance of <class '__main__.Foo'>

Давайте разберёмся, что здесь происходит. Когда Вы пытаетесь распечатать объект, интерпретатор обращается к его методам __str__() и __repr__(). Мы можем переопределить один из них и получить красивый вывод:


class Foo:
    def __str__(self):
        return 'Foo object'

print(f'{Foo()} is instance of {Foo}')
# Вывод:
Foo object is instance of <class '__main__.Foo'>

Многострочные F-Strings

Как уже говорилось, у вас могут быть многострочные f-strings, но, если Вы забудете поставить «f» в начале каждой строки, Вы получите совсем не то, чего ожидали:


print(f'1 + 1 = {1 + 1}n'
    '2 + 2 = {2 + 2}')
# Вывод:
1 + 1 = 2
2 + 2 = {2 + 2}

Но у Вас есть возможность использовать «f» перед тройными кавычками, тогда всё сработает:


print(f"""1 + 1 = {1 + 1}
2 + 2 = {2 + 2}""")
# Вывод:
1 + 1 = 2
2 + 2 = 4

Скорость

Одной из целей создания форматированных строковых литералов являлось увеличение скорости по сравнению с, уже существовавшим на тот момент, методом строки .format(). И это цель была достигнута. Давайте проверим это утверждение:


import timeit

var_1 = timeit.timeit("""
язык = 'Python'
проценты = 100
'-Самый лучший язык - %s. -Точно? -%d' % (язык, проценты) + '%!'
""", number=10000)
var_2 = timeit.timeit("""
язык = 'Python'
проценты = 100
'-Самый лучший язык - {}. -Точно? {}'.format(язык, проценты) + '%!'
""", number=10000)
var_3 = timeit.timeit("""
язык = 'Python'
проценты = 100
f'-Самый лучший язык - {язык}. -Точно? {проценты}' + '%!'
""", number=10000)
var_4 = timeit.timeit("""
язык = 'Python'
проценты = 100
'-Самый лучший язык - ' + язык + '. -Точно? ' + str(проценты) + '%!'
""", number=10000)
time_sum = var_1 + var_2 + var_3 + var_4
var_1, var_2, var_3, var_4 = [round(i / time_sum * 100) for i in (var_1, var_2, var_3, var_4)]
print('Строковый оператор форматирования: ', var_1, '%', sep='')
print('Метод .format(): ', var_2, '%', sep='')
print('Форматированный строковый литерал: ', var_3, '%', sep='')
print('Конкатенация: ', var_4, '%', sep='')
# Вывод:
Строковый оператор форматирования: 26%
Метод .format(): 31%
Форматированный строковый литерал: 17%
Конкатенация: 27%

Конкатенация здесь приведена просто для наглядности. Как видите, «f»-Строки выигрывают в скорости.
При добавлении циклов вызова, разница остаётся такой же:


import timeit

var_2 = timeit.timeit("""
язык = 'Python'
проценты = 100
'-Самый лучший язык - {}. -Точно? {}'.format(язык, проценты) + '%!'
""", number=10000000)
var_3 = timeit.timeit("""
язык = 'Python'
проценты = 100
f'-Самый лучший язык - {язык}. -Точно? {проценты}' + '%!'
""", number=10000000)

time_sum = var_2 + var_3
var_2, var_3 = [round(i / time_sum * 100) for i in (var_2, var_3)]

print('Метод .format(): ', var_2, '%', sep='')
print('Форматированный строковый литерал: ', var_3, '%', sep='')
# Вывод:
Метод .format(): 65%
Форматированный строковый литерал: 35%

Python F-Строки: Детали

На данный момент мы узнали почему f-строки так хороши, так что вам уже может быть интересно их попробовать в работе. Рассмотрим несколько деталей, которые нужно учитывать:

Кавычки

Вы можете использовать несколько видов кавычек внутри выражений. Удостоверьтесь в том, что вы не применяете один и тот же тип кавычек внутри и снаружи f-строки.
Этот код будет работать:


print(f'{"Python"}')
# Вывод:
Python

И этот тоже:


print(f"{'Python'}")
# Вывод:
Python

Вы также можете применить тройные кавычки:


print(f"""{"Python"}""")
# Вывод:
Python

Если вам понадобиться использовать один и тот же тип кавычек внутри и снаружи строки, вам может помочь :


print(f''Lorem' 'ipsum' 'dolor' 'sit' 'amet'')
# Вывод:
'Lorem' 'ipsum' 'dolor' 'sit' 'amet'

Словари

Говоря о кавычках, будьте внимательны при работе со словарями Python. Вы можете вставить значение словаря по его ключу, но ключ и сама строка должны быть обрамлены разными кавычками:


arg_dict = {'язык': 'Python', 'проценты': 100}

print(f"-Самый лучший язык - {arg_dict['язык']}.n"
    f"-Точно?n"
    f"-{arg_dict['проценты']}%!")
# Вывод:
-Самый лучший язык - Python.
-Точно?
-100%!

Обратите внимание на количество возможных проблем, если допустить ошибку в синтаксисе SyntaxError:


arg_dict = {'язык': 'Python', 'проценты': 100}

print(f'-Самый лучший язык - {arg_dict['язык']}.n'
    f'-Точно?n'
    f'-{arg_dict['проценты']}%!')
# Вывод:
File "C:UsersivandAppDataRoamingJetBrainsPyCharm2021.2scratchesscratch_1.py", line 3
print(f'-Самый лучший язык - {arg_dict['язык']}.n'
                             ^
SyntaxError: f-string: unmatched '['

Process finished with exit code 1

Скобки

Чтобы скобки появились в строке, вам нужно использовать двойные фигурные скобки:


print(f'-Самый лучший язык - {{Python}}.n'
    f'-Точно?n'
    f'-{{100}}%!')
# Вывод:
-Самый лучший язык - {Python}.
-Точно?
-{100}%!

Обратите внимание на то, что применение тройных фигурных скобок приведет к тому, что в строке будут только одинарные:


print(f'{{{1}}}')
# Вывод:
{1}

В целом, здесь мы имеем такое же неочевидное поведение, как и у метода строки .format():


print(f'{{{{{{{{1}}}}}}}}')
# Вывод:
{{{{1}}}}

Бэкслеши

Несмотря на то, что бэкслеш можно использовать в строке, у Вас не получится сделать это внутри выражения:


print(f'{"1n2"}')
# Вывод:
File "C:UsersivandAppDataRoamingJetBrainsPyCharm2021.2scratchesscratch_1.py", line 1
print(f'{"1n2"}')
           ^
SyntaxError: f-string expression part cannot include a backslash

Process finished with exit code 1

Вы можете проработать это, оценивая выражение заранее и используя результат в f-строк:


temp = "1n2"
print(f'{temp}')
# Вывод:
1
2

Междустрочные комментарии

Выражения не должны содержать комментарии с применением октоторпа (символ «#»). В противном случае, у вас будет ошибка синтаксиса SyntaxError:


print(f'2 + 2 = {4 # наверно}')
# Вывод:
File "C:UsersivandAppDataRoamingJetBrainsPyCharm2021.2scratchesscratch_1.py", line 1
print(f'2 + 2 = {4 # наверно}')
                   ^
SyntaxError: f-string expression part cannot include '#'

Process finished with exit code 1

Форматирование вставляемых выражений

Форматированные строковые литералы, как и метод строки .format() поддерживают форматирование:


print(f'2 + 2 = {2 + 2:010d}')
# Вывод:
2 + 2 = 0000000004
print(f'2 + 2 = {2 + 2:^010d}')
# Вывод:
2 + 2 = 0000400000
print(f'2 + 2 = {"четыре":.3}')
# Вывод:
2 + 2 = чет
заполнитель = '_'
выравнивание = '^'
ширина = 9
язык = 'Питон'
print(f"{язык:{заполнитель}{выравнивание}{ширина}}")
# Вывод:
__Питон__

Подробнее об этом читайте в нашем предыдущем уроке.

Python f-strings are impressive!

Did you know you can use f-strings to string format almost anything in Python?

You can use them to format floats, multiline strings, decimal places, objects and even use if-else conditionals within them.

In this post, I’ll show you at least 73 examples on how to format strings using Python 3’s f-strings. You’ll see the many ways you can take advantage of this powerful feature.

By the end of this guide, you’ll have mastered:

  • how to use f string to format float numbers
  • how to format multiline string
  • how to define decimal places in a f-string
  • how to fix invalid syntax errors such as «syntaxerror: f-string: unmatched ‘[‘» or f-string: unmatched ‘(‘
  • how to use if else statement in a f-string
  • basic string interpolation formatting using f-strings
  • how to print f-strings
  • how to effectively add padding using fstring

Let’s go!

Table of Contents

  1. What Are Python 3’s F-Strings — a.k.a Literal String Interpolation?
  2. How to Format Strings in Python 3 — The Basics
  3. Limitations
  4. How to Format an Expression
  5. How to Use F-Strings to Debug Your Code
  6. How to Format a Multiline F-String (Dealing with New Lines and Variables)
  7. How to Fix F-String’s Invalid Syntax Error
  8. How to Fix «formatting a regular string which could be a f-string»
  9. How to Format Numbers in Different Bases
  10. How to Print Formatted Objects With F-Strings
  11. How to Use F-Strings to Format a Float
  12. How to Format a Number as Percentage
  13. How to Justify or Add Padding to a F-String
  14. How to Escape Characters With f-string
  15. How to Add a Thousand Separator

    15.1. How to Format a Number With Commas as Decimal Separator

    15.2. How to Format a Number With Spaces as Decimal Separator

  16. How to Format a Number in Scientific Notation (Exponential Notation)
  17. Using if-else Conditional in a F-String
  18. How to Use F-String With a Dictionary
  19. How to Concatenate F-Strings
  20. How to Format a Date With F-String
  21. How to Add Leading Zeros
  22. Conclusion

What Are Python F-Strings — a.k.a Literal String Interpolation?

String formatting has evolved quite a bit in the history of Python. Before Python 2.6, to format a string, one would either use the % operator, or string.Template module. Some time later, the str.format method came along and added to the language a more flexible and robust way of formatting a string.

Old string formatting with %:

>>> msg = 'hello world'
>>> 'msg: %s' % msg
'msg: hello world'

Using string.format:

>>> msg = 'hello world'
>>> 'msg: {}'.format(msg)
'msg: hello world'

To simplify formatting even further, in 2015, Eric Smith proposed the
PEP 498 — Literal String Interpolation
, a new way to format a string for python 3.

PEP 498 presented this new string interpolation to be a simple and easy to use alternative to str.format. The only thing required is to put a ‘f’ before a string. And if you’re new to the language, that’s what f in Python means, it’s a new syntax to create formatted strings.

Using f-strings:

>>> msg = 'hello world'
>>> f'msg: {msg}'
'msg: hello world'

And that was it! No need to use str.format or %. However, f-strings don’t replace str.format completely. In this guide I’ll show you an example where they are not suitable.

How to Format Strings in Python 3 — The Basics

As I have shown in the previous section, formatting strings in python using f-strings is quite straightforward. The sole requirement is to provide it a valid expression. f-strings can also start with capital F and you can combine with raw strings to produce a formatted output. However, you cannot mix them with bytes b"" or "u".

fig_5.png

>>> book = "The dog guide"

>>> num_pages = 124

>>> f"The book {book} has {num_pages} pages"
'The book The dog guide has 124 pages'

>>> F"The book {book} has {num_pages} pages"
'The book The dog guide has 124 pages'

>>> print(Fr"The book {book} has {num_pages} pagesn")
The book The dog guide has 124 pagesn

>>> print(FR"The book {book} has {num_pages} pagesn")
The book The dog guide has 124 pagesn

>>> print(f"The book {book} has {num_pages} pagesn")
The book The dog guide has 124 pages

And that’s pretty much it! In the next section, I’ll show you several examples of everything you can do — and cannot do — with f-strings.

Limitations

Even though f-strings are very convenient, they don’t replace str.format completely. f-strings evaluate expressions in the context where they appear. According the the PEP 498
, this means the expression has full access to local and global variables. They’re also an expression evaluated at runtime. If the expression used inside the { <expr> } cannot be evaluated, the interpreter will raise an exception.

>>> f"{name}"
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-f0acc441190f> in <module>
----> 1 f"{name}"

NameError: name 'name' is not defined

This is not a problem for the str.format method, as you can define the template string and then call .format to pass on the context.

>>> s = "{name}"

>>> s.format(name="Python")
'Python'

>>> print(s)
{name}

Another limitation is that you cannot use inline comments inside a f-string.

>>> f"My name is {name #name}!"
  File "<ipython-input-37-0ae1738dd871>", line 1
    f"My name is {name #name}!"
    ^
SyntaxError: f-string expression part cannot include '#'

How to Format an Expression

If you don’t want to define variables, you can use literals inside the brackets. Python will evaluate the expression and display the final result.

>>> f"4 * 4 is {4 * 4}"
'4 * 4 is 16'

Or if you prefer…

>>> n = 4

>>> f"4 * 4 is {n * n}"
'4 * 4 is 16'

How to Use F-Strings to Debug Your Code

One of most frequent usages of f-string is debugging. Before Python 3.8, many people would do hello = 42; f"hello = {hello}", but this is very repetitive. As a result, Python 3.8 brought a new feature. You can re-write that expression as f"{hello=}" and Python will display hello=42. The following example illustrates this using a function, but the principle is the same.

>>> def magic_number():
     ...:     return 42
     ...: 

>>> f"{magic_number() = }"
'magic_number() = 42'

How to Format a Multiline F-String (Dealing with New Lines and Variables)

You can use the newline character n with f-strings to print a string in multiple lines.

>>> multi_line = (f'R: {color["R"]}nG: {color["G"]}nB: {color["B"
    ...: ]}n')

>>> multi_line
'R: 123nG: 145nB: 255n'

>>> print(multi_line)
R: 123
G: 145
B: 255

As an alternative, you can use triple quotes to represent the multiline string with variables. It not only allows you to add line breaks, it’s also possible to add TAB.

>>> other = f"""R: {color["R"]}
    ...: G: {color["G"]}
    ...: B: {color["B"]}
    ...: """

>>> print(other)
R: 123
G: 145
B: 255

Example with TABs.

>>> other = f'''
    ...: this is an example
    ...: 
    ...: ^Iof color {color["R"]}
    ...:     
    ...: '''

>>> other
'nthis is an examplenntof color 123n    n'

>>> print(other)

this is an example

    of color 123



>>>

How to Fix F-String’s Invalid Syntax Error

If not used correctly, f-strings can raise a SyntaxError. The most common cause is using double-quotes inside a double quoted f-string. The same is also true for single quotes.

>>> color = {"R": 123, "G": 145, "B": 255}

>>> f"{color["R"]}"
  File "<ipython-input-43-1a7f5d512400>", line 1
    f"{color["R"]}"
    ^
SyntaxError: f-string: unmatched '['


# using only single quotes
>>> f'{color['R']}'
  File "<ipython-input-44-3499a4e3120c>", line 1
    f'{color['R']}'
    ^
SyntaxError: f-string: unmatched '['

This error not only happens with '[', but also '('. The cause is the same, it happens when you close a quote prematurely.

>>> print(f"price: {format(round(12.345), ",")}")
  File "<ipython-input-2-1ae6f786bc4d>", line 1
    print(f"price: {format(round(12.345), ",")}")
                                           ^
SyntaxError: f-string: unmatched '('

To fix that, you need to use single quotes.

>>> print(f"price: {format(round(12.345), ',')}")
price: 12

>>> color = {"R": 123, "G": 145, "B": 255}

>>> f"{color['R']}"
'123'

>>> f'{color["R"]}'
'123'

Another common case is to use f-strings in older versions of Python. f-strings were introduced in Python 3.6. If you use it in an older version, the interpreter will raise a SyntaxError: invalid syntax.

>>> f"this is an old version"
  File "<stdin>", line 1
    f"this is an old verion"
                            ^
SyntaxError: invalid syntax

If you see invalid syntax, make sure to double check the Python version you are running. In my case, I tested in on Python 2.7, and you can find the version by calling sys.version.

>>> import sys; print(sys.version)
2.7.18 (default, Apr 20 2020, 19:27:10) 
[GCC 8.3.0]

How to Fix «formatting a regular string which could be a f-string»

This error happens because pylint detects the old way of formatting string such as using % or the str.format method.

C0209: Formatting a regular string which could be a f-string (consider-using-f-string)

To fix that you can either:

  • replace the old formatting method with a f-string
  • ignore the pylint error using

In this post, I explain how to fix this issue step-by-step.

Replacing with f-strings

The following examples illustrate how to convert old method to f-string.

>>>  ip_address = "127.0.0.1"

# pylint complains if we use the methods below
>>> "http://%s:8000/" % ip_address
'http://127.0.0.1:8000/'

>>> "http://{}:8000/".format(ip_address)
'http://127.0.0.1:8000/'

# Replace it with a f-string
>>> f"http://{ip_address}:8000/"
'http://127.0.0.1:8000/'

Disable pylint

Alternatively, you can disable pylint by specifying the «disable» flag with the error code.

>>>  ip_address = "127.0.0.1"

# pylint complains if we use the methods below, so we can disable them
>>> "http://%s:8000/" % ip_address  # pylint: disable=C0209
'http://127.0.0.1:8000/'

>>> "http://{}:8000/".format(ip_address)  # pylint: disable=C0209
'http://127.0.0.1:8000/'

Another way of disabling that error is to add it to the .pylintrc file.

# .pylintrc
disable=
    ...
    consider-using-f-string,
    ...

There’s yet another way of disabling it, which is by placing a comment at the top of the file, like so:

 # pylint: disable=consider-using-f-string

def your_function(fun):
    """Your code below"""
    ...

How to Format Numbers in Different Bases

fig_6.png

f-strings also allow you to display an integer in different bases. For example, you can display an int as binary without converting it by using the b option.

>>> f'{7:b}'
'111'

In summary, you can use f-strings to format:

  • int to binary
  • int to hex
  • int to octal
  • int to HEX (where all chars are capitalized)

The following example uses the padding feature and the base formatting to create a table that displays an int in other bases.

>>> bases = {
       "b": "bin", 
       "o": "oct", 
       "x": "hex", 
       "X": "HEX", 
       "d": "decimal"
}
>>> for n in range(1, 21):
     ...:     for base, desc in bases.items():
     ...:         print(f"{n:5{base}}", end=' ')
     ...:     print()

    1     1     1     1     1 
   10     2     2     2     2 
   11     3     3     3     3 
  100     4     4     4     4 
  101     5     5     5     5 
  110     6     6     6     6 
  111     7     7     7     7 
 1000    10     8     8     8 
 1001    11     9     9     9 
 1010    12     a     A    10 
 1011    13     b     B    11 
 1100    14     c     C    12 
 1101    15     d     D    13 
 1110    16     e     E    14 
 1111    17     f     F    15 
10000    20    10    10    16 
10001    21    11    11    17 
10010    22    12    12    18 
10011    23    13    13    19 
10100    24    14    14    20

How to Print Formatted Objects With F-Strings

You can print custom objects using f-strings. By default, when you pass an object instance to a f-string, it will display what the __str__ method returns. However, you can also use the explicit conversion flag to display the __repr__.

!r - converts the value to a string using repr().
!s - converts the value to a string using str().
>>> class Color:
    def __init__(self, r: float = 255, g: float = 255, b: float = 255):
        self.r = r
        self.g = g
        self.b = b

    def __str__(self) -> str:
        return "A RGB color"

    def __repr__(self) -> str:
        return f"Color(r={self.r}, g={self.g}, b={self.b})"

>>> c = Color(r=123, g=32, b=255)

# When no option is passed, the __str__ result is printed
>>> f"{c}"
'A RGB color'

# When `obj!r` is used, the __repr__ output is printed
>>> f"{c!r}"
'Color(r=123, g=32, b=255)'

# Same as the default
>>> f"{c!s}"
'A RGB color'

Python also allows us to control the formatting on a per-type basis through the __format__ method. The following example shows how you can do all of that.

>>> class Color:
    def __init__(self, r: float = 255, g: float = 255, b: float = 255):
        self.r = r
        self.g = g
        self.b = b

    def __str__(self) -> str:
        return "A RGB color"

    def __repr__(self) -> str:
        return f"Color(r={self.r}, g={self.g}, b={self.b})"

    def __format__(self, format_spec: str) -> str:
        if not format_spec or format_spec == "s":
            return str(self)

        if format_spec == "r":
            return repr(self)

        if format_spec == "v":
            return f"Color(r={self.r}, g={self.g}, b={self.b}) - A nice RGB thing."

        if format_spec == "vv":
            return (
                f"Color(r={self.r}, g={self.g}, b={self.b}) "
                f"- A more verbose nice RGB thing."
            )

        if format_spec == "vvv":
            return (
                f"Color(r={self.r}, g={self.g}, b={self.b}) "
                f"- A SUPER verbose nice RGB thing."
            )

        raise ValueError(
            f"Unknown format code '{format_spec}' " "for object of type 'Color'"
        )

>>> c = Color(r=123, g=32, b=255)

>>> f'{c:v}'
'Color(r=123, g=32, b=255) - A nice RGB thing.'

>>> f'{c:vv}'
'Color(r=123, g=32, b=255) - A more verbose nice RGB thing.'

>>> f'{c:vvv}'
'Color(r=123, g=32, b=255) - A SUPER verbose nice RGB thing.'

>>> f'{c}'
'A RGB color'

>>> f'{c:s}'
'A RGB color'

>>> f'{c:r}'
'Color(r=123, g=32, b=255)'

>>> f'{c:j}'
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-1c0ee8dd74be> in <module>
----> 1 f'{c:j}'

<ipython-input-15-985c4992e957> in __format__(self, format_spec)
     29                 f"- A SUPER verbose nice RGB thing."
     30             )
---> 31         raise ValueError(
     32             f"Unknown format code '{format_spec}' " "for object of type 'Color'"
     33         )

ValueError: Unknown format code 'j' for object of type 'Color'

Lastly, there’s also the a option that escapes non-ASCII chars. For more info: docs.python.org/3/library/functions.html#as..

>>> utf_str = "Áeiöu"

>>> f"{utf_str!a}"
"'\xc1ei\xf6u'"

How to Use F-Strings to Format a Float

f-strings allow format float numbers similar to str.format method. To do that, you can add a : (colon) followed by a . (dot) and the number of decimal places with a f suffix.

For instance, you can round a float to 2 decimal places and print the variable just like this:

>>> num = 4.123956

>>> f"num rounded to 2 decimal places = {num:.2f}"
'num rounded to 2 decimal places = 4.12'

If you don’t specify anything, the float variable will use the full precision.

>>> print(f'{num}')
4.123956

How to Format a Number as Percentage

Python f-strings have a very convenient way of formatting percentage. The rules are similar to float formatting, except that you append a % instead of f. It multiplies the number by 100 displaying it in a fixed format, followed by a percent sign. You can also specify the precision.

>>> total = 87

>>> true_pos = 34

>>> perc = true_pos / total

>>> perc
0.39080459770114945

>>> f"Percentage of true positive: {perc:%}"
'Percentage of true positive: 39.080460%'

>>> f"Percentage of true positive: {perc:.2%}"
'Percentage of true positive: 39.08%'

How to Justify or Add Padding to a F-String

You can justify a string quite easily using < or > characters.

how to justify or add padding to a string in python

>>> greetings = "hello"

>>> f"She says {greetings:>10}"
'She says      hello'

# Pad 10 char to the right
>>> f"{greetings:>10}"
'     hello'

>>> f"{greetings:<10}"
'hello     '

# You can omit the < for left padding
>>> f"{greetings:10}"
'hello     '

fig_2.png

>>> a = "1"

>>> b = "21"

>>> c = "321"

>>> d = "4321"

>>> print("n".join((f"{a:>10}", f"{b:>10}", f"{c:>10}", f"{d:>10}")))
         1
        21
       321
      4321

How to Escape Characters With f-string

In case you want to display the variable name surrounded by the curly brackets instead of rendering its value, you can escape it using double {{<expr>}}.

>>> hello = "world"

>>> f"{{hello}} = {hello}"
'{hello} = world'

Now, if you want to escape a double quote, you can use the backslash ".

>>> f"{hello} = "hello""
'world = "hello"'

How to Center a String

fig_1.png

Centering a string can be achieved by using var:^N where var is a variable you want to display and N is the string length. If N is shorter than the var, then Python display the whole string.

>>> hello = "world"

>>> f"{hello:^11}"
'   world   '

>>> f"{hello:*^11}"
'***world***'

# Extra padding is added to the right
>>> f"{hello:*^10}"
'**world***'

# N shorter than len(hello)
>>> f"{hello:^2}"
'world'

How To Add a Thousand Separator

fig_4.png

f-strings also allow us to customize numbers. One common operation is to add an underscore to separate every thousand place.

>>> big_num = 1234567890

>>> f"{big_num:_}"
'1_234_567_890'

How to Format a Number With Commas as Decimal Separator

In fact, you can use any char as separator. It’s also possible to use a comma as separator.

>>> big_num = 1234567890

>>> f"{big_num:,}"
'1,234,567,890'

You can also format a float with commas and set the precision in one go.

>>> num = 2343552.6516251625

>>> f"{num:,.3f}"
'2,343,552.652'

How to Format a Number With Spaces as Decimal Separator

What about using spaces instead?

Well, this one is a bit “hacky” but it works. You can use the , as separator, then replace it with space.

>>> big_num = 1234567890

>>> f"{big_num:,}".replace(',', ' ')
'1 234 567 890'

Another option is to set the locale of your environment to one that uses spaces as a thousand separator such as pl_PL. For more info, see this thread on stack overflow.

How to Format a Number in Scientific Notation (Exponential Notation)

Formatting a number in scientific notation is possible with the e or E option.

>>> num = 2343552.6516251625

>>> f"{num:e}"
'2.343553e+06'

>>> f"{num:E}"
'2.343553E+06'

>>> f"{num:.2e}"
'2.34e+06'

>>> f"{num:.4E}"
'2.3436E+06'

Using if-else Conditional in a F-String

f-strings also evaluates more complex expressions such as inline if/else.

>>> a = "this is a"

>>> b = "this is b"

>>> f"{a if 10 > 5 else b}"
'this is a'

>>> f"{a if 10 < 5 else b}"
'this is b'

How to Use F-String With a Dictionary

You can use dictionaries in a f-string. The only requirement is to use a different quotation mark than the one enclosing the expression.

>>> color = {"R": 123, "G": 145, "B": 255}

>>> f"{color['R']}"
'123'

>>> f'{color["R"]}'
''123'

>>> f"RGB = ({color['R']}, {color['G']}, {color['B']})"
'RGB = (123, 145, 255)'

How to Concatenate F-Strings

Concatenating f-strings is like concatenating regular strings, you can do that implicitly, or explicitly by applying the + operator or using str.join method.

# Implicit string concatenation
>>> f"{123}" " = " f"{100}" " + " f"{20}" " + " f"{3}"
'123 = 100 + 20 + 3'

# Explicity concatenation using '+' operator
>>> f"{12}" + " != " + f"{13}"
'12 != 13'

# string concatenation using `str.join`
>>> " ".join((f"{13}", f"{45}"))
'13 45'

>>> "#".join((f"{13}", f"{45}"))
'13#45'

How to Format a Date With F-String

f-strings also support the formatting of datetime objects. The process is very similar to how str.format formats dates. For more info about the supported formats, check this table in the official docs.

fig_7.png

>>> import datetime

>>> now = datetime.datetime.now()

>>> ten_days_ago = now - datetime.timedelta(days=10)

>>> f'{ten_days_ago:%Y-%m-%d %H:%M:%S}'
'2020-10-13 20:24:17'

>>> f'{now:%Y-%m-%d %H:%M:%S}'
'2020-10-23 20:24:17'

How to Add Leading Zeros

You can add leading zeros by adding using the format {expr:0len} where len is the length of the returned string. You can include a sign option. In this instance, + means the sign should be used for positive and negative numbers. The - is used only for negative numbers, which is the default behavior. For more info, check the string format specification page .

>>> num = 42

>>> f"{num:05}"
'00042'

>>> f'{num:+010}'
'+000000042'

>>> f'{num:-010}'
'0000000042'

>>> f"{num:010}"
'0000000042'

>>> num = -42

>>> f'{num:+010}'
'-000000042'

>>> f'{num:010}'
'-000000042'

>>> f'{num:-010}'
'-000000042'

Conclusion

That’s it for today, folks! I hope you’ve learned something different and useful. Knowing how to make the most out of f-string can make our lives so much easier. In this post, I showed the most common tricks I use in a day-to-day basis.

Other posts you may like:

  • How to Check if an Exception Is Raised (or Not) With pytest
  • Everything You Need to Know About Python’s Namedtuples
  • The Best Way to Compare Two Dictionaries in Python
  • 11 Useful Resources To Learn Python’s Internals From Scratch
  • 7 pytest Features and Plugins That Will Save You Tons of Time

See you next time!

Понравилась статья? Поделить с друзьями:
  • Unlocker ошибка нет привилегий отладки
  • Unlock tool ошибка 1004
  • Unlock act of war high treason ошибка
  • Unknown произошла неизвестная ошибка пожалуйста перезапустите игру
  • Unknown ошибка самп