2015-12-21 3 views
0

В Python есть ли способ сделать getattr() на модуле для пакетов? Другими словами, существует ли способ поиска функции в пакете, подобном приведенному ниже?Getattr on package in 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... except с getattr найти какой модуль содержит нужный класс или (вы также можете импортировать любой другой объект верхнего уровня)

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