Python格式化字符串字面值中f_expression的星号及yield表达式用法疑问
你看到的f_expression语法规则,本质是Python把完整的表达式语法直接复用到了f-string的大括号里,没有做额外限制,你疑惑的两种用法都属于通用Python表达式的范畴,不是f-string专属特性。
*开头的表达式用法
你写的{(*a)}报错的核心原因是单独的星号解包表达式不能独立作为值存在,它只能在序列、集合、字典的构造上下文里使用。
语法里的"*" or_expr规则是和后面的逗号规则配套的,对应Python通用的「可迭代对象解包构造序列」语法,合法写法示例:
a = [1, 2, 3] # 解包为元组,加逗号即可识别为元组构造 print(f"test1: {*a,}") # 输出:test1: (1, 2, 3) # 解包后和其他元素拼接为新元组 print(f"test2: {*a, 4, 5, *[6, 7]}") # 输出:test2: (1, 2, 3, 4, 5, 6, 7) # 解包为集合 print(f"test3: {{*a, 3, 4}}") # 输出:test3: {1, 2, 3, 4}
这个特性的实用价值是可以在f-string里直接完成可迭代对象的解包拼接,不需要额外定义中间变量。
yield_expression的用法
f-string没有为yield做任何特殊适配,只是因为yield本身是Python的合法表达式,所以语法上允许放在大括号里,实际开发中几乎没有使用价值,属于语法规则自然覆盖到的边角情况。
你给出的示例运行逻辑如下:
- 生成器
testit启动后,执行到f-string的位置时会先运行yield 125,把125返回给调用方,所以第一行输出125,生成器在此处暂停。 - 由于你没有调用
send()方法给生成器传值,yield 125表达式的默认返回值是None,生成器恢复执行后就会把这个None格式化进字符串,所以第二行输出test: None。
如果主动给生成器传值,就能看到yield表达式的返回值变化:
def testit(): print(f'test: {yield 125}') g = testit() print(next(g)) # 启动生成器,输出125 g.send("hello") # 给yield传值,输出 test: hello
内容的提问来源于stack exchange,提问作者Afshin
相关产品推荐
相关产品推荐

