从Python AST获取与具有给定名称的特定变量相对应的所有节点
考虑以下代码:从Python AST获取与具有给定名称的特定变量相对应的所有节点,python,abstract-syntax-tree,Python,Abstract Syntax Tree,考虑以下代码: 1 | x = 20 2 | 3 | def f(): 4 | x = 0 5 | for x in range(10): 6 | x += 10 7 | return x 8 | f() 9 | 10| for x in range(10): 11| pass 12| x += 1 13| print(x) 执行上述代码后,x的值为10。现在,我如何获得所有具有类Name且ids为x的节点,并参考第1、10、12和13行中使用
1 | x = 20
2 |
3 | def f():
4 | x = 0
5 | for x in range(10):
6 | x += 10
7 | return x
8 | f()
9 |
10| for x in range(10):
11| pass
12| x += 1
13| print(x)
执行上述代码后,x
的值为10
。现在,我如何获得所有具有类Name
且id
s为x
的节点,并参考第1、10、12和13行中使用的x
换句话说,
f
内部的x
与x
s的其余部分不同。是否可以获取其AST节点,仅具有脚本和脚本的AST而不执行它?在遍历AST树时,跟踪上下文;从全局上下文开始,然后当遇到FunctionDef
或ClassDef
或Lambda
节点时,将该上下文记录为堆栈(退出相关节点时再次弹出堆栈)
然后,只需查看全局上下文中的Name
节点即可。您还可以跟踪global
标识符(我会在每个堆栈级别使用一组)
使用:
演示(给定t
中示例代码的AST树):
并在函数中使用global x
:
>>> u = ast.parse('''\
... x = 20
...
... def g():
... global x
... x = 0
... for x in range(10):
... x += 10
... return x
...
... g()
... for x in range(10):
... pass
... x += 1
... print(x)
... ''')
>>> GlobalUseCollector('x').visit(u)
x used at line 1
x used at line 5
x used at line 6
x used at line 7
x used at line 8
x used at line 11
x used at line 13
x used at line 14
在Python 3.5+中,还应该为
async def
函数定义visit\u async functiondef(self,node)
。@pahaz一个别名就足够了:visit\u async functiondef=visit\u functdef
>>> GlobalUseCollector('x').visit(t)
x used at line 1
x used at line 10
x used at line 12
x used at line 13
>>> u = ast.parse('''\
... x = 20
...
... def g():
... global x
... x = 0
... for x in range(10):
... x += 10
... return x
...
... g()
... for x in range(10):
... pass
... x += 1
... print(x)
... ''')
>>> GlobalUseCollector('x').visit(u)
x used at line 1
x used at line 5
x used at line 6
x used at line 7
x used at line 8
x used at line 11
x used at line 13
x used at line 14