回答(15)
2 years ago
为了完整性,我想指出有时您可能想要解析代码而不是导入代码 . import 将执行顶级表达式,这可能是个问题 .
例如,我让用户为使用zipapp制作的包选择入口点函数 . 使用 import 和 inspect 冒着运行误入代码的风险,导致崩溃,帮助打印出消息,弹出GUI对话框等等 .
相反,我使用ast模块列出所有顶级函数:
import ast
import sys
def top_level_functions(body):
return (f for f in body if isinstance(f, ast.FunctionDef))
def parse_ast(filename):
with open(filename, "rt") as file:
return ast.parse(file.read(), filename=filename)
if __name__ == "__main__":
for filename in sys.argv[1:]:
print(filename)
tree = parse_ast(filename)
for func in top_level_functions(tree.body):
print(" %s" % func.name)
将此代码放在 list.py 中并使用自身作为输入,我得到:
$ python list.py list.py
list.py
top_level_functions
parse_ast
当然,导航AST有时会很棘手,即使是像Python这样相对简单的语言,因为AST非常低级 . 但是如果你有一个简单明了的用例,它既可行又安全 .
但是,缺点是您无法检测在运行时生成的函数,如 foo = lambda x,y: x*y .
2 years ago
如果您无法导入所述Python文件而没有导入错误,这些答案都不会起作用 . 当我检查一个来自具有大量依赖关系的大型代码库的文件时,我就是这种情况 . 以下将文件作为文本处理,并搜索以“def”开头的所有方法名称并打印它们及其行号 .
import re
pattern = re.compile("def (.*)\(")
for i, line in enumerate(o