Why isn't it possible to use backslashes in f-strings?
Solution 1
You seem to expect
'{}'.format("new\nline")
and
f'{"new\nline"}'
to be equivalent. That's not what I would expect, and it's not how backslashes in f-strings worked back in the pre-release versions of Python 3.6 where backslashes between the braces were allowed. Back then, you'd get an error because
"new
line"
is not a valid Python expression.
As just demonstrated, backslashes in the braces are confusing and ambiguous, and they were banned to avoid confusion:
The point of this is to disallow convoluted code like:
>>> d = {'a': 4} >>> f'{d[\'a\']}' '4'
In addition, I'll disallow escapes to be used for brackets, as in:
>>> f'\x7bd["a"]}' '4'
(where chr(0x7b) == "{").
Solution 2
It's annoying that you can't do this:
things = ['Thing one','Thing two','Thing three']
print(f"I have a list of things: \n{'\n'.join(things)}")
But you can do this:
things = ['Thing one','Thing two','Thing three']
nl = '\n'
print(f"I have a list of things:\n{nl.join(things)}")
Solution 3
For new lines, you can use os.linesep
instead of \n
. For example:
>>> import os
>>>
>>> print(f"Numbers:\n{os.linesep.join(map(str, [10, 20, 30]))}")
Numbers:
10
20
30
Related videos on Youtube
Comments
-
jmd_dk almost 2 years
In Python >=3.6, f-strings can be used as a replacement for the
str.format
method. As a simple example, these are equivalent:'{} {}'.format(2+2, "hey") f'{2+2} {"hey"}'
Disregarding format specifiers, I can basically move the positional arguments of
str.format
inside braces in an f-string. Note specifically that I am allowed to just putstr
literals in here, although it may seem a bit unwieldy.There are however some limitations. Specifically, backslashes in any shape or form are disallowed inside the braces of an f-string:
'{}'.format("new\nline") # legal f'{"new\nline"}' # illegal f'{"\\"}' # illegal
I cannot even use
\
to split up a long line if it's inside the braces;f'{2+\ 2}' # illegal
even though this usage of
\
is perfectly allowed inside normalstr
's;'{\ }'.format(2+2) # legal
It seems to me that a hard stop is coded into the parser if it sees the
\
character at all inside the braces of an f-string. Why is this limitation implemented? Though the docs specify this behavior, it does not justify why.-
miradulo over 5 yearsSee Let’s make escaping in f-literals impossible and the conclusion Changes to PEP 498 (f-strings)
-
-
Guimoute about 5 yearsAgreed backslashes in braces are confusing, but backslashes outside are not permitted either and that is too bad. This example is not confusing:
f"Make your selection \n A- {textA} \n B- {textB} \n C- {textC}"
. -
Rebs about 3 yearsAlso the use of textwrap.dedent is totally broken for multi-line f-strings, as the default case is to begin the dedent with a line-continuation `dedent('''\`. This is plain broken imo and the bizarre purist attitudes like this from the py3 devs only serve to hurt the user.
-
Steven Oxley almost 3 years@Guimoute Your non-confusing example is perfectly legal (in Python 3.7.8, at least):
f"Make your selection \n A- {textA} \n B- {textB} \n C- {textC}"
. I believe backslashes are only disallowed inside braces. -
benrg over 2 yearsThe correct line separator for
print
is'\n'
on all platforms, but on Windowsos.linesep
is'\r\n'
(ref). I think'\n' == chr(10)
is guaranteed, so you can writechr(10).join(...)
, though it feels hacky.