Getattr на пакет в Python
В Python есть ли эквивалент getattr()
на модуле для пакетов? Другими словами, есть ли способ найти функцию в пакете, подобную приведенной ниже?
Intents/
|-- __init__.py
|-- foo.py
|-- bar.py
|-- baz.py
2 ответа
Решение
Ты можешь использовать 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