Getattr在Python上打包

时间:2015-12-21 16:00:13

标签: python python-2.7 getattr

在Python中,是否有相当于在包的模块上执行getattr()?换句话说,有没有办法在包中搜索一个如下面的函数?

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

2 个答案:

答案 0 :(得分:1)

您可以使用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... except放在getattr中以查找哪个模块包含所需的类或函数(您还可以导入任何其他顶级对象)

答案 1 :(得分:0)

如果找到该函数,您并没有真正说出您想要返回的内容,因此以下只返回模块名称。

如果您将以下函数定义添加到__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