采用以下代码:
k = 'A'
d = {}
d[k := k.lower()] = 'b'
print(k)
print(d)
这给出了人们所期望的输出:
a
{'a': 'b'}
然而,对于我的一个项目中的类似代码,flake 8抱怨这样的海象表达是一个语法错误(至少在python3.8的github运行器上是这样;在我的计算机上似乎没有问题).
所以我的问题是,海象表达是否必须始终位于括号内,或者此类情况是否也正确.
采用以下代码:
k = 'A'
d = {}
d[k := k.lower()] = 'b'
print(k)
print(d)
这给出了人们所期望的输出:
a
{'a': 'b'}
然而,对于我的一个项目中的类似代码,flake 8抱怨这样的海象表达是一个语法错误(至少在python3.8的github运行器上是这样;在我的计算机上似乎没有问题).
所以我的问题是,海象表达是否必须始终位于括号内,或者此类情况是否也正确.
它不需要用在方括号或括号中.
例如,在if
块中:
k = 'A'
if l:=k.lower() == 'a':
print(l)
或者:
s = ' a '
if x:=s.strip():
print(x)
PEP 572给出了一些需要括号的具体情况:
有几个地方不允许使用分配公式, 为了避免歧义或用户混淆:
- 在表达陈述的顶层禁止使用无括号的分配表达.示例:
y := f(x) # INVALID (y := f(x)) # Valid, though not recommended
包含此规则是为了简化用户在分配陈述和分配表达之间的 Select -没有 两者都有效的语法位置.
- 禁止在指定陈述右侧的顶层使用无括号的指定表达式.示例:
y0 = y1 := f(x) # INVALID y0 = (y1 := f(x)) # Valid, though discouraged
同样,包含此规则是为了避免两种视觉上相似的方式来表达同一件事.
- 对于调用中的关键字参数的值,禁止使用无括号的分配公式.示例:
foo(x = y := f(x)) # INVALID foo(x=(y := f(x))) # Valid, though probably confusing
包含此规则是为了不允许代码过于混乱,并且因为解析关键字参数已经足够复杂.
- 禁止在函数默认值的顶层使用无括号的分配公式.示例:
def foo(answer = p := 42): # INVALID ... def foo(answer=(p := 42)): # Valid, though not great style ...
包含此规则是为了防止其确切语义已经让许多用户感到困惑的位置产生副作用(参见的 针对可变默认值的常见风格建议),而且 以呼应电话中的类似禁令(上一个项目).
- 禁止无括号的分配公式作为参数、返回值和分配的注释.示例:
def foo(answer: p := 42 = 5): # INVALID ... def foo(answer: (p := 42) = 5): # Valid, but probably never useful ...
这里的推理与前两个 case 相似;这个由:和=组成的未分组符号和运算符分类是 很难正确阅读.
- Lambda函数中禁止使用无括号的分配公式.示例:
(lambda: x := 1) # INVALID lambda: (x := 1) # Valid, but unlikely to be useful (x := lambda: 1) # Valid lambda line: (m := re.match(pattern, line)) and m.group(1) # Valid
这使得ambda的绑定始终不像:=那么紧密;在ambda函数内部的顶层具有名称绑定不太可能 是有价值的,因为没有办法利用它.在 名称将被使用多次,该表达可能需要 无论如何,添加括号,因此这项禁令很少影响代码.
- f字符串内部的分配公式需要括号.示例:
>>> f'{(x:=10)}' # Valid, uses assignment expression '10' >>> x = 10 >>> f'{x:=10}' # Valid, passes '=10' to formatter ' 10'
这表明,f字符串中看起来像是指派运算符的东西并不总是指派运算符.f字符串解析器 用途:指示格式选项.向后保存 兼容性,f字符串内部的分配运算符使用必须是 加括号.如上所述,分配运算符的这种使用 不建议.