如何使用 AST 从 Python 代码中检索函数名称和属性?
How can I retrieve function names and attributes from Python code with AST?
给定一段这样的代码:
aaa = bbb()
ccc.ddd().eee(fff(foo))
ggg(bar)
hhh().iii
我想得到这样的东西:
['bbb', 'ccc.ddd.eee', 'fff', 'ggg', 'hhh.iii']
我知道 visit_Call
和 visit_Name
方法,但我无法将它们设为 return 仅函数名称或带有对象调用函数的函数名称 return 由这些函数编辑(如 foo().bar())。
要生成 function-attribute 查找路径,您需要遍历 ast.AST
对象,检查是否有任何 ast.Call
或 ast.Attribute
,如果找到的话,然后您将需要遍历这些对象,并在它们出现时保存名称和属性。下面的递归模式遍历主 AST
(parse
) 并利用辅助函数 (parse_chain
) 遍历任何属性或调用存在的名称:
import ast
def parse(d, c):
def parse_chain(d, c, p=[]):
if isinstance(d, ast.Name):
return [d.id]+p
if isinstance(d, ast.Call):
for i in d.args:
parse(i, c)
return parse_chain(d.func, c, p)
if isinstance(d, ast.Attribute):
return parse_chain(d.value, c, [d.attr]+p)
if isinstance(d, (ast.Call, ast.Attribute)):
c.append('.'.join(parse_chain(d, c)))
else:
for i in getattr(d, '_fields', []):
if isinstance(t:=getattr(d, i), list):
for i in t:
parse(i, c)
else:
parse(t, c)
results = []
s = """
aaa = bbb()
ccc.ddd().eee(fff(foo))
ggg(bar)
hhh().iii
"""
parse(ast.parse(s), results)
print(results)
输出:
['bbb', 'fff', 'ccc.ddd.eee', 'ggg', 'hhh.iii']
给定一段这样的代码:
aaa = bbb()
ccc.ddd().eee(fff(foo))
ggg(bar)
hhh().iii
我想得到这样的东西:
['bbb', 'ccc.ddd.eee', 'fff', 'ggg', 'hhh.iii']
我知道 visit_Call
和 visit_Name
方法,但我无法将它们设为 return 仅函数名称或带有对象调用函数的函数名称 return 由这些函数编辑(如 foo().bar())。
要生成 function-attribute 查找路径,您需要遍历 ast.AST
对象,检查是否有任何 ast.Call
或 ast.Attribute
,如果找到的话,然后您将需要遍历这些对象,并在它们出现时保存名称和属性。下面的递归模式遍历主 AST
(parse
) 并利用辅助函数 (parse_chain
) 遍历任何属性或调用存在的名称:
import ast
def parse(d, c):
def parse_chain(d, c, p=[]):
if isinstance(d, ast.Name):
return [d.id]+p
if isinstance(d, ast.Call):
for i in d.args:
parse(i, c)
return parse_chain(d.func, c, p)
if isinstance(d, ast.Attribute):
return parse_chain(d.value, c, [d.attr]+p)
if isinstance(d, (ast.Call, ast.Attribute)):
c.append('.'.join(parse_chain(d, c)))
else:
for i in getattr(d, '_fields', []):
if isinstance(t:=getattr(d, i), list):
for i in t:
parse(i, c)
else:
parse(t, c)
results = []
s = """
aaa = bbb()
ccc.ddd().eee(fff(foo))
ggg(bar)
hhh().iii
"""
parse(ast.parse(s), results)
print(results)
输出:
['bbb', 'fff', 'ccc.ddd.eee', 'ggg', 'hhh.iii']