В Python есть ли способ сделать getattr()
на модуле для пакетов? Другими словами, существует ли способ поиска функции в пакете, подобном приведенному ниже?Getattr on package in Python
Intents/
|-- __init__.py
|-- foo.py
|-- bar.py
|-- baz.py
В Python есть ли способ сделать getattr()
на модуле для пакетов? Другими словами, существует ли способ поиска функции в пакете, подобном приведенному ниже?Getattr on package in Python
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... except
с getattr
найти какой модуль содержит нужный класс или (вы также можете импортировать любой другой объект верхнего уровня)
Вы действительно не сказали точно, что вы хотели вернуть, если функция найдена, поэтому следующее просто возвращает имя модуля.
Если вы добавили следующее определение функции для вашего __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
Не отвечает ли это на ваш вопрос? – martineau
Для этого потребуется импортировать все модули в пакете , Это приемлемо? – martineau
Это приемлемо, все они будут совсем маленькими. –