Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么不是';不能在f字符串中使用反斜杠吗?_Python_Python 3.x_String Formatting_Backslash_F String - Fatal编程技术网

Python 为什么不是';不能在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

在Python>=3.6中,可以使用f字符串替换
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