如何使用 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_Callvisit_Name 方法,但我无法将它们设为 return 仅函数名称或带有对象调用函数的函数名称 return 由这些函数编辑(如 foo().bar())。

要生成 function-attribute 查找路径,您需要遍历 ast.AST 对象,检查是否有任何 ast.Callast.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']