Я работаю над сменной системой, где сменные модули загружаются как это:
def load_plugins():
plugins=glob.glob("plugins/*.py")
instances=[]
for p in plugins:
try:
name=p.split("/")[-1]
name=name.split(".py")[0]
log.debug("Possible plugin: %s", name)
f, file, desc=imp.find_module(name, ["plugins"])
plugin=imp.load_module('plugins.'+name, f, file, desc)
getattr(plugin, "__init__")(log)
instances=instances+plugin.get_instances()
except Exception as e:
log.info("Failed to load plugin: "+str(p))
log.info("Error: %s " % (e))
log.info(traceback.format_exc(e))
return instances
Работы кода, но для каждого оператора импорта в сменном коде я получаю предупреждение как это:
plugins/plugin.py:2: RuntimeWarning: Parent module 'plugins' not found while handling absolute import
import os
Ни о каких ошибках не сообщают для основного кода программы и работы плагинов.
Может кто-то объяснять, что предупреждение означает и что я делающий неправильно. Я должен создать пустой модуль плагинов отдельно и импортировать его для угождения Python?
Если бы каталог подключаемых модулей
был реальным пакетом (содержащим __ init __. py
нормально), вы можете легко использовать pkgutils для перечисления файлов плагинов и их загрузки.
import pkgutil
# import our package
import plugins
list(pkgutil.iter_modules(plugins.__path__))
Тем не менее, он все равно может работать без пакета плагина, попробуйте следующее:
import pkgutil
list(pkgutil.iter_modules(["plugins"]))
Также можно создать пакет, который существует только во время выполнения:
import types
import sys
plugins = types.ModuleType("plugins")
plugins.__path__ = ["plugins"]
sys.modules["plugins"] = plugins
import plugins.testplugin
Однако этот хак был в основном для развлечения!
Если в каталоге плагинов нет __ init __. Py
, это не пакет, поэтому, когда вы создаете plugins.whatever
, Python предупреждает вас, что такое не должно на самом деле не существует. (Он не может быть создан с помощью « import plugins.whatever
», независимо от вашего пути.)
Кроме того,
/
, что непереносимый. Используйте os.path.split
. .split (". Py")
для получения имени без расширения, это ошибочно. Используйте os.path.splitext
. getattr
со строковым литералом. getattr (plugin, «__init __»)
пишется как plugin .__ init __
. __ init __
. Это не кажется правильным. Возможно, вам нужна функция "set_logger" или лучше, чтобы создать экземпляр класса, который принимает регистратор. L = L + some_other_list
для расширения списка, используйте метод extend
, который имеет лучшую производительность и более идиоматичен. , кроме исключения
. Если вы не можете запланировать что-то разумное в ответ на исключение, ваша программа не сможет нормально работать.