如果我理解正确,在Python3中,条件表达式的形式是" x如果C else y"。例如,如果我理解正确,下面的块是一个条件表达式,它返回字符串' a'
'a' if 0<1 else 'b'
而以下块是一个返回&#39; b&#39;
的条件表达式'a' if 0>1 else 'b'
在Python语言参考中,grammar rule for conditional expressions由这些行给出:
conditional_expression ::= or_test ["if" or_test "else" expression]
我不理解这条规则,因为例如我会在上面的例子中说'a'
和0>1
来自or_test
而'b'
是派生自expression
,而对我来说'a'
和'b'
都应该通过相同的规则派生(expr
此处)。对我来说唯一有意义的就是用
conditional_expression ::= expression \["if" or_test "else" expression\]
我在这里缺少什么?
答案 0 :(得分:1)
简而言之:因为它会引入歧义。
我不明白这个规则,因为例如我会在上面的例子中说
'a'
和0>1
来自or_test
而'b'
来自表达式,而对我而言,'a'
和'b'
都应该使用相同的规则(expr
此处)来推导。
or_test
和expr
都可以生成字符串文字。事实上,如果我们向下移动语法,我们会看到:
or_test ::= and_test | or_test "or" and_test
and_test ::= not_test | and_test "and" not_test
not_test ::= comparison | "not" not_test
comparison ::= or_expr ( comp_operator or_expr )*
or_expr ::= xor_expr | or_expr "|" xor_expr
xor_expr ::= and_expr | xor_expr "^" and_expr
and_expr ::= shift_expr | and_expr "&" shift_expr
shift_expr ::= a_expr | shift_expr ( ">" ) a_expr
a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr
m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr
| m_expr "%" u_expr
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
power ::= primary ["**" u_expr]
primary ::= atom | attributeref | subscription | slicing | call
atom ::= identifier | literal | enclosure
literal ::= stringliteral | bytesliteral
| integer | floatnumber | imagnumber
因此最终or_test
可以导致字符串文字。您可以看到or_test
作为表达式,但在某些情况下不再可能(除非我们使用括号)。
我们无法对or_test
执行的两件重要事情是再次构建if
- then
- else
;并构造一个lambda表达式。是的,我们可以将第一个项目设为lambda表达式,将新if
- then
设置为else
,但不能不使用括号。
为什么我们这有必要?一个语法应该是毫不含糊的。这意味着如果我们从某个表达式构造语法树,那么应该只有一个这样的树。
如果我们允许使用expression
作为第一项,我们可以编写如下表达式:
'a' if a else 'b' if c else 'c'
现在我们可以在Python中编写它,因为Python可以推导出'a'
属于or_test
,a
属于第二个or_test
,'b' if c else 'c'
到expression
。如果前者是表达式,我们也可以将'a' if a else 'b'
与表达式匹配(根据 Python 标准,这是错误的。)
使用lambda表达式也是如此。如果我们写:
lambda a, b: 'a' if a else 'b' if c else 'c'
然后Python会将其解析为:
lambda a, b: ('a' if a else 'b' if c else 'c')
但是如果我们在第一个or_test
中启用lambda表达式,那么Python也可以将它解析为:
(lambda a, b: 'a') if a else 'b' if c else 'c'
这本身并不是本身错误,但Python的设计者选择了前者对后者的解释。重要的是只能有一个解释,否则两个人可以使用不同的解释器运行相同的Python程序,并获得不同的结果。