代码之家  ›  专栏  ›  技术社区  ›  Eric McLachlan

在Python中,如何获取在特定文件中定义的类列表?

  •  0
  • Eric McLachlan  · 技术社区  · 5 年前

    如果一个文件 myfile.py

    class A(object):
      # Some implementation
    
    class B (object):
      # Some implementation
    

    我如何定义一个方法,以便 myfile.py文件 ,它返回

    这里,A和B的返回值可以是类的名称或类的类型。

    (i.e. type(A) = type(str) or type(A) = type(type))

    0 回复  |  直到 5 年前
        1
  •  5
  •   Sebastian Nielsen    4 年前

    你可以同时得到:

    import importlib, inspect
    for name, cls in inspect.getmembers(importlib.import_module("myfile"), inspect.isclass):
    

    if cls.__module__ == 'myfile'
    
        2
  •  2
  •   match    5 年前

    它有点冗长,但首先需要将文件作为模块加载,然后检查其方法以查看哪些是类:

    import inspect
    import importlib.util
    
    # Load the module from file
    spec = importlib.util.spec_from_file_location("foo", "foo.py")
    foo = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(foo)
    
    # Return a list of all attributes of foo which are classes
    [x for x in dir(foo) if inspect.isclass(getattr(foo, x))]
    
        3
  •  1
  •   Eric McLachlan    5 年前

    我将X的所有子类保存在一个特定的文件夹(包)中,然后,使用这个方法,我可以加载X的所有子类,即使它们还没有被导入。(如果尚未导入,则无法通过 __all__ 否则事情会容易得多)。

    import importlib, os, inspect
    
    def get_modules_in_package(package_name: str):
        files = os.listdir(package_name)
        for file in files:
            if file not in ['__init__.py', '__pycache__']:
                if file[-3:] != '.py':
                    continue
    
                file_name = file[:-3]
                module_name = package_name + '.' + file_name
                for name, cls in inspect.getmembers(importlib.import_module(module_name), inspect.isclass):
                    if cls.__module__ == module_name:
                        yield cls