Python 中包的 Getattr

Getattr on package in Python

在 Python 中,是否有等同于在包的模块上执行 getattr() 的操作?换句话说,有没有一种方法可以像下面这样在包中搜索函数?

Intents/
|-- __init__.py
|-- foo.py
|-- bar.py
|-- baz.py

您可以使用 getattr 从 python 模块中获取任何对象:

In [4]: cat bla.py

def foo():
    pass

In [5]: import bla


In [6]: getattr( bla, 'foo')
Out[6]: <function bla.foo>

所以你可以遍历一个包中的所有模块,然后 try... exceptgetattr 找到哪个模块包含所需的 class 或功能(你也可以导入任何其他顶级对象)

如果找到函数,您并没有真正准确地说出您想要返回什么,所以下面只是 returns 模块名称。

如果您将以下函数定义添加到 __init__.py 文件中:

def find_func(func_name):
    """ Return name of package module that contains named function. """
    import os
    import sys
    import traceback
    import types

    # dynamically imports all the python modules in sub directory
    package_path = os.path.split(__file__)[0]
    package_directory = os.path.split(package_path)[1]

    for fn in os.listdir(package_directory):
        globals_, locals_ = globals(), locals()
        # process all python files in directory that don't start with underscore
        if fn[0] != '_' and fn.split('.')[-1] in ('py', 'pyw'):
            modulename = fn.split('.')[0]  # filename without extension
            subpackage = ".".join([package_directory, modulename])
            try:
                module = __import__(subpackage, globals_, locals_, [modulename])
            except:
                traceback.print_exc(file=sys.stdout)
                raise  # reraise exception
            # see if this module has the named function
            obj = getattr(module, func_name, None)
            if isinstance(obj, (types.FunctionType, types.LambdaType)):
                return modulename

    return None  # not found

然后您可以在客户端包中执行以下操作:

import Intents

print(Intents.find_func('func_in_bar'))  # --> bar