Python 为什么不是';不能在f字符串中使用反斜杠吗?
在Python>=3.6中,可以使用f字符串替换Python 为什么不是';不能在f字符串中使用反斜杠吗?,python,python-3.x,string-formatting,backslash,f-string,Python,Python 3.x,String Formatting,Backslash,F String,在Python>=3.6中,可以使用f字符串替换str.format方法。作为一个简单的例子,这些是等效的: '{} {}'.format(2+2, "hey") f'{2+2} {"hey"}' 不管怎样,我基本上可以将str.format的位置参数移动到f字符串中的大括号中。请特别注意,我只允许在这里输入strliterals,尽管这看起来有点笨拙 但也有一些限制。特别是,不允许在f字串的大括号内使用: '{}'.format("new\nline") # legal f'{"new\n
str.format
方法。作为一个简单的例子,这些是等效的:
'{} {}'.format(2+2, "hey")
f'{2+2} {"hey"}'
不管怎样,我基本上可以将str.format
的位置参数移动到f字符串中的大括号中。请特别注意,我只允许在这里输入str
literals,尽管这看起来有点笨拙
但也有一些限制。特别是,不允许在f字串的大括号内使用:
'{}'.format("new\nline") # legal
f'{"new\nline"}' # illegal
f'{"\\"}' # illegal
我甚至不能使用\
来拆分大括号内的长线
f'{2+\
2}' # illegal
即使在正常的str
中完全允许使用\
'{\
}'.format(2+2) # legal
在我看来,如果在f字符串的大括号内看到\
字符,则硬停止代码会被编码到解析器中。为什么要实施这一限制?虽然指定了这种行为,但它不能解释为什么。您似乎期望
'{}'.format("new\nline")
及
相当于。这不是我所期望的,这也不是在Python3.6的预发行版本中,f字符串中的反斜杠是如何工作的,在该版本中,大括号之间的反斜杠是允许的。那时,你会得到一个错误,因为
"new
line"
不是有效的Python表达式
正如刚才所演示的,大括号中的反斜杠容易混淆和歧义,它们是为了避免混淆:
这一点是不允许使用卷积代码,如:
>>> d = {'a': 4}
>>> f'{d[\'a\']}'
'4'
此外,我将不允许在括号中使用转义符,如:
>>> f'\x7bd["a"]}'
'4'
(其中chr(0x7b)=“{”)
你不能做到这一点真让人恼火:
things = ['Thing one','Thing two','Thing three']
print(f"I have a list of things: \n{'\n'.join(things)}")
但你可以这样做:
things = ['Thing one','Thing two','Thing three']
nl = '\n'
print(f"I have a list of things:\n{nl.join(things)}")
对于新行,可以使用
os.linesep
而不是\n
。例如:
>>> import os
>>>
>>> print(f"Numbers:\n{os.linesep.join(map(str, [10, 20, 30]))}")
Numbers:
10
20
30
请看和结论@miradulo请将其作为答案发布。@Bakuriu我将在30秒后前往AFK,如果您愿意,请随意发布。我也认为这违反了“最小惊讶原则”。事实上,我很惊讶它没有接受“\n”字符。我为生活编写Ruby代码,你可以在
{}
插值中编写各种语法正确的Ruby代码。大括号中的反斜杠令人困惑,但大括号外的反斜杠也不允许,这太糟糕了。这个例子并不令人困惑:f“做出选择\n A-{textA}\n B-{textB}\n C-{textC}“
@Guimoute:但是接下来的问题是\{
还是\x7b
启动一个替换字段。是的。可能只允许\n
、\t
和\r
启动。令人惊讶的是,我刚刚发现f/.\\caution
不会引发错误,而且打印效果良好。@Guimoute您不易混淆的示例是完全合法的(至少在Python 3.7.8中):f“进行选择\n A-{textA}\n B-{textB}\n C-{textC}”
。我相信反斜杠只在大括号内是不允许的。@StevenOxley是的,我现在对这个例子没有问题。不幸的是,我不知道2年多前发表原始评论时的情况是否如此。对于多行f字符串,textwrap.dedent的使用也完全被打破,因为默认情况是开始使用dedent w这是一个断章取义的句子,py3开发者的这种古怪的纯粹主义态度只会伤害用户。
>>> import os
>>>
>>> print(f"Numbers:\n{os.linesep.join(map(str, [10, 20, 30]))}")
Numbers:
10
20
30