简短回答
:
+=
是一个
增量赋值
如果我们考虑到语法,在语法树中解析的语法比一般的运算符(因此
/
尤其是操作员)。
Python看到
+=
作为“
增量赋值
“。如果我们检查
Python grammar
我们看到:
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
现在语法也强制
优先规则
解析时。如果我们看看与
stmt
(“
陈述
“”我们看到:
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
('=' (yield_expr|testlist_star_expr))*)
详尽地解释所有其他陈述(如
del_statement
)会花太长时间,但是
expr_stmt
是唯一一个导致
augassign
(和)
增广赋值
是导致
+=
令牌)。所以我们可以忽略其他表达式。
如果我们把
EXPRO-STMT
这样它就有了
增广赋值
在里面,我们取回
产生式规则
:
expr_stmt: testlist_star_expr augassign (yield_expr|testlist)
这个
testlist_star_expr
是导致标识符(或序列解包时的多个标识符)等的变量。
在右边我们看到一个
yield_expr
,或者
test_list
. 一
测试列表
可能导致逗号分隔的表达式,其中:
testlist: test (',' test)* [',']
这个
test
允许写入三元运算符,但这是
不
强制性的:
test: or_test ['if' or_test 'else' test] | lambdef
我们可以接受
or_test
变量,用于将表达式与
or
分隔符(也是可选的),因为
或
具有最高优先级。
or_test: and_test ('or' and_test)*
然后跟随
and_test
顾名思义,这让我们可以写
and
运营商:
and_test: not_test ('and' not_test)*
然后跟随
not
操作员(与
not_test
):
not_test: 'not' not_test | comparison
我们可以有任意数量的
不
在前面,但最终我们会选择
comparison
.
如果我们看一下
比较
我们看到:
comparison: expr (comp_op expr)*
这样就允许
比较器链
,像
x <= y < z
,接下来我们来看看
expr
:
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
所以这定义了优先规则,我们看到了
|
优先于
^
,优先于
&
等等,直到我们看到
term
是一个序列
factor
s与运算符
'*'
,
'@'
,
'/'
,
'%'
和
//
在这里,我们终于“消费”了
*
. 这意味着
/
在语法树中低于
+=
节点。
因此,python解析此表达式的方式是:
a += (b / 2)