【问题标题】:Iterate over directory and get function names from found .py files遍历目录并从找到的 .py 文件中获取函数名称
【发布时间】:2019-11-19 13:15:59
【问题描述】:

我有以下问题:

假设我有一个目录,在这个目录中是另一个目录,其中包含一个具有以下功能的 hello_world.py 文件:

def print_hello_world():
   print("Hello World")

层次结构:folder1/folder2/hello_world.py

现在我在文件夹 1 中有一个 print_function_names.py 文件,用于检查文件夹 2 是否存在,然后我遍历文件夹 2 中的 .py 文件并打印函数名称。在这个测试场景中,输出是:

print_hello_world

我的第一种方法是打开文件并使用正则表达式查找函数名称。

folder1/print_function_names.py

with open("folder1/folder2/hello_world.py", "r") as file:
    for line in file.readlines():
        if re.match("def (.*)\(", line):
            function_name = re.match("def (.*)\(", line)
            print(function_name.group(1))

有没有更 Pythonic 或者更简单的方法?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

如 cmets 中所述,您可以使用 ast 模块来解析 python 文件,而无需使用正则表达式/任何其他解决方法来查找所有函数。这是一个解析给定 python 文件中定义的所有函数的示例

import ast

def find_methods_in_python_file(file_path):
    methods = []
    o = open(file_path, "r")
    text = o.read()
    p = ast.parse(text)
    for node in ast.walk(p):
        if isinstance(node, ast.FunctionDef):
            methods.append(node.name)

    print(methods)


find_methods_in_python_file('folder2/wtf.py')

要查找一个目录下的所有python文件,可以使用this问题,然后迭代并调用find_methods_in_python_file

【讨论】:

    【解决方案2】:

    您可以使用Abstract Syntax Trees 在 python 代码中查找函数定义(不仅如此!)。这是一个短代码 sn-p 应该打印文件中的所有函数定义:

    import ast
    
    class FuncLister(ast.NodeVisitor):
    
        def visit_FunctionDef(self, node):
            print('FunctionDef', node.name)
            self.generic_visit(node)
    
    with open('path/to/python/file.py', 'r') as f:
        tree = ast.parse(f.read())
        print(FuncLister().visit(tree))
    

    这将打印该文件中的所有函数定义。将它放在一个循环中,该循环遍历目录中的文件,并且您在目录中拥有所有函数定义名称。

    【讨论】:

      【解决方案3】:

      您可以在 python 中将hello_world 文件作为模块导入,然后检查其中的元素,检查功能:

      In [1]: import types
         ...: import folder1.folder2.hello_world as hello_world
         ...: for name in dir(hello_world):
         ...:     elt = getattr(hello_world, name)
         ...:     if type(elt) == types.FunctionType:
         ...:         print(elt.__name__)
         ...:
      print_hello_world
      

      如果您将模块路径作为字符串,例如file_path = 'folder1/folder2/hello_world.py',那么就可以使用了

      import importlib
      module_path = file_path.replace('/', '.')[:-3]
      module = importlib.import_module(module_path)
      

      【讨论】:

        猜你喜欢
        • 2019-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-09
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多