Динамический класс, загружающийся в Python 2.6: RuntimeWarning: Родительский модуль 'плагины', не найденные при обработке абсолютного импорта

Я работаю над сменной системой, где сменные модули загружаются как это:

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?

23
задан pehrs 15 February 2010 в 18:13
поделиться

2 ответа

Если бы каталог подключаемых модулей был реальным пакетом (содержащим __ 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

Однако этот хак был в основном для развлечения!

14
ответ дан 29 November 2019 в 02:11
поделиться

Если в каталоге плагинов нет __ 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 , который имеет лучшую производительность и более идиоматичен.
  • Не подавляйте неизвестные исключения с помощью , кроме исключения . Если вы не можете запланировать что-то разумное в ответ на исключение, ваша программа не сможет нормально работать.
16
ответ дан 29 November 2019 в 02:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: