6

Python 3.12 Preview: More Intuitive and Consistent F-Strings

 1 year ago
source link: https://realpython.com/python312-f-strings/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

F-Strings Had Some Limitations Before Python 3.12

You can use Python’s f-strings for string formatting and interpolation. An f-string is a string literal prefixed with the letter F, either in uppercase or lowercase. This kind of literal lets you interpolate variables and expressions, which Python evaluates to produce the final string.

F-strings have gained a lot of popularity in the Python community since their introduction in Python 3.6. People have embraced them with enthusiasm, turning them into a standard in modern Python programming. The reasons? They provide a concise and readable syntax that allows you to format strings and interpolate variables and expressions without needing the .format() method or the old-style string formatting operator (%).

However, to introduce f-strings, the CPython core development team had to decide how to implement them, especially how to parse them. As a result, f-strings came with their own parsing code. In other words, CPython has a dedicated parser for f-strings. Because of this, the f-string grammar isn’t part of the official Python grammar.

From the core developers’ point of view, this implementation decision implies considerable maintenance costs because they have to manually maintain a separate parser. On the other hand, not being part of the official grammar means that other Python implementations, such as PyPy, can’t know if they’ve implemented f-strings correctly.

However, the most important burden is on the user’s side. From the user’s perspective, the current f-string implementation imposes some limitations:

  • Reusing quotes or string delimiters isn’t possible.
  • Embedding backslashes isn’t possible, which means you can’t use escape characters.
  • Adding inline comments is forbidden.
  • Nesting of f-strings is limited to the available quoting variations in Python.

PEP 536 lists these limitations. However, exploring them with a few small examples will help you understand how they can affect your use of f-strings in your Python code.

Note: The examples that you’ll see in this section use Python 3.11. If you have a lower Python version installed, then you may get different output.

First, say that you need to interpolate a dictionary key in an f-string. If you try the following code, then you’ll get an error:

>>> employee = {
...     "name": "John Doe",
...     "age": 35,
...     "job": "Python Developer",
... }

>>> f"Employee: {employee["name"]}"
  File "<stdin>", line 1
    f"Employee: {employee["name"]}"
                           ^^^^
SyntaxError: f-string: unmatched '['

In this example, you try to interpolate the employee name in your f-strings. However, you get an error because the double quotes around the "name" key break the string literal. To work around this, you need to use a different type of quotation mark to delimit the key:

>>> f"Employee: {employee['name']}"
'Employee: John Doe'

Now you use double quotes for the f-string and single quotes for the dictionary key. Your code works now, but having to switch quotes can get annoying at times.

The second limitation of f-strings is that you can’t use backslash characters in embedded expressions. Consider the following example, where you try to concatenate strings using the newline (\n) escape sequence:

>>> words = ["Hello", "World!", "I", "am", "a", "Pythonista!"]

>>> f"{'\n'.join(words)}"
  File "<stdin>", line 1
    f"{'\n'.join(words)}"
                         ^
SyntaxError: f-string expression part cannot include a backslash

In this example, you get a SyntaxError because f-strings don’t allow backslash characters inside expressions delimited by curly brackets. Again, you can implement a work-around, but it’s not exactly pretty:

>>> word_lines = "\n".join(words)

>>> f"{word_lines}"
'Hello\nWorld!\nI\nam\na\nPythonista!'

>>> print(f"{word_lines}")
Hello
World!
I
am
a
Pythonista!

In this example, you run the string concatenation, store the result in a variable, and finally have the f-string interpolate that variable’s content. This approach avoids the backslash issue, but it feels like something is wrong with f-strings. Why don’t they allow all valid Python expressions?

Another limitation of f-strings is that they don’t allow you to insert comments in embedded expressions. This limitation may seem superfluous, but in some cases, a good comment can help other developers better understand your code:

>>> employee = {
...     "name": "John Doe",
...     "age": 35,
...     "job": "Python Developer",
... }

>>> f"""Storing employee's data: {
...     employee['name'].upper()  # Always uppercase name before storing
... }"""
  File "<stdin>", line 3
    }"""
        ^
SyntaxError: f-string expression part cannot include '#'

In this example, you use triple quotes to build a string that spans multiple lines. When you try to add an inline comment beside the interpolated expression, you get a SyntaxError. This behavior seems weird because you can add comments in a normal Python expression wrapped in brackets. So, embedded expressions in f-strings don’t work as normal Python expressions do.

Finally, f-strings have another limitation. The number of nesting levels in an f-string is limited by the available string delimiters in Python, which are ", ', """, and '''. In the following example, you run into the issue:

>>> f"""{
...     f'''{
...         f"{f'{42}'}"
...     }'''
... }"""
'42'

>>> f"""{
...     f'''{
...         f"{f'{f"{42}"}'}"
...     }'''
... }"""
  File "<stdin>", line 1
    (f"{f'{f"{42}"}'}")
             ^
SyntaxError: f-string: f-string: unterminated string

Even though nesting f-strings may not have many use cases, you’ll probably find some interesting ones. If you need an additional level of nesting in a specific use case, then you’re out of luck because you can’t reuse quotes.

It’s important to note that only triple-quoted f-strings can span multiple lines. However, this isn’t a big issue because that’s the expected behavior of Python strings, where only triple-quoted strings can occupy multiple lines.

While f-strings are pretty cool, and most Python developers love them, all these limitations make them feel incomplete and inconsistent with the general behavior of Python itself. Fortunately, Python is constantly improving, and the next version, 3.12, is lifting these limitations to make f-strings even better.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK