Является ли использование __import __ ('module_name') антипаттерном в Python?

В настоящее время я занимаюсь рефакторингом проекта Python 2, который включает возможность добавлять или удалять плагины, которые представляют собой модули Python, реализующие данный API.

Основное приложение получает доступ к добавлению /удалению /обновлению хуков в плагинах, например, вызывая __import__('plugin_name').hook_add() после извлечения имен плагинов из базы данных, но это похоже на хакерский подход. Сказав это, я не знаю лучших способов программного доступа к плагинам.

Считается ли это антипаттерном в Python?

1 голос | спросил Jules 17 Maypm16 2016, 15:44:17

1 ответ


2
  

Использует ли __import__('module_name') антипаттерн в Python?

API для __import__ несколько вводит в заблуждение. Я лично предпочел бы избежать этого, где это возможно.

документы для состояния Python 3:

  

Прямое использование __import__() также не рекомендуется в пользу importlib.import_module()

Вот API для __import__:

mod = __import__(
    module, # string of dotted name
    globals=None, # only needed to do relative import
    locals=None, # implementation ignores this
    fromlist=()) # fromlist just needs to be non-empty... :(
    level=0 # relative import, not going into this part
    )

Если fromlist пуст, вы импортируете модуль, но получаете корневой пакет, подобный этому, поэтому вы должны выполнить точечный поиск, чтобы вернуться к нему:

>>> foo = __import__('foo.bar.baz')
>>> foo.bar.baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>

Это то же самое, что и

>>> import foo.bar.baz
>>> foo.bar.baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>

Если вы просто хотите, чтобы модуль был не пустым, список from:

>>> baz = __import__('foo.bar.baz', fromlist=[None])
>>> baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>

Что совпадает с

>>> from foo.bar import baz
>>> baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>

>>> baz is foo.bar.baz
True

Вместо этого используйте importlib.import_module:

Вот пример использования import_module :

>>> from importlib import import_module
>>> baz = import_module('foo.bar.baz')

Это намного приятнее.

ответил Aaron Hall 18 Maypm16 2016, 18:51:13

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132