为何ast.Assign.targets是列表?多元素场景条件解析
ast.Assign.targets的两个问题 问题1:为何ast.Assign.targets是列表?
Python的赋值语法支持多种场景,把targets设计成列表是为了统一所有赋值场景的AST结构,不管是单个变量赋值、解包赋值还是多变量共享赋值,都能通过列表来承载目标节点,避免为不同赋值形式单独设计节点类型。
比如你给出的示例代码:
a, b = c, d
对应的AST里,targets列表中只包含一个Tuple节点,这个节点对应解包的两个变量。而像x = 1这种单变量赋值,targets就是[Name(id='x', ctx=Store())];像x = y = 1这种多变量共享赋值,targets会是[Name(id='x', ctx=Store()), Name(id='y', ctx=Store())]。用列表统一处理这些情况,能让AST结构更一致,也方便后续的语法分析和代码处理。
问题2:在什么情况下targets会是包含多个元素的列表,而非单个Tuple?
当你使用多目标共享赋值(多个变量或目标同时接收同一个值)时,targets就会是包含多个独立节点的列表,而非单个Tuple。
举几个典型例子:
- 多变量同时赋值同一个值:
x = y = z = 100
对应的AST中,targets是[Name(id='x', ctx=Store()), Name(id='y', ctx=Store()), Name(id='z', ctx=Store())],每个元素都是独立的变量节点。
- 混合解包和单变量的共享赋值:
x, y = z = (1, 2)
这个语句等同于让z先接收元组(1,2),再把z解包给x和y,对应的AST里targets列表会包含两个元素:一个Tuple节点(对应x,y)和一个Name节点(对应z),结构大致如下:
Assign( targets=[ Tuple(elts=[Name(id='x', ctx=Store()), Name(id='y', ctx=Store())], ctx=Store()), Name(id='z', ctx=Store()) ], value=Tuple(elts=[Constant(value=1), Constant(value=2)], ctx=Load()) )
简单来说,只要是多个独立的赋值目标共享同一个赋值表达式,targets就会是包含多个元素的列表,每个元素对应一个单独的目标节点(可以是变量、属性、下标访问等,不一定是元组)。
内容的提问来源于stack exchange,提问作者mr0re1

