2015-12-21 76 views
0

在Python中,是否有相当于在包的模块上做getattr()?换句话说,是否有一种方法可以在下面的包中搜索一个函数?Getattr在Python中的封装

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

这样做将需要进口的所有模块的封装。这可以接受吗? – martineau

+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... exceptgetattr找到哪个模块包含所需的类或函数(您也可以导入任何其他顶级对象)

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 
+0

这不是回答你的问题吗? – martineau