Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python AST获取与具有给定名称的特定变量相对应的所有节点_Python_Abstract Syntax Tree - Fatal编程技术网

从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