2015-01-30 1 views
20

Я заметил, что Flask использовал Werkzeug до __import__ модуля, и я был немного смущен. Я пошел и проверил документы на нем и увидел, что это, кажется, дает вам больше контроля как-то с точки зрения того, где он ищет модуль, но я не уверен точно как и у меня нет идеи, как он отличается от importlib.import_module ,import vs __import __() vs importlib.import_module()?

Невероятная вещь в примере Werkzeug заключается в том, что она просто говорит __import__(import_name), поэтому я не вижу, как это отличается от того, как просто используется оператор import, так как он игнорирует дополнительные дополнительные параметры.

Может ли кто-нибудь объяснить? Я смотрел на других людей, которые задавали аналогичные вопросы на SO ранее, но они были не очень четко сформулированы вопросы, и ответы не касались этого вообще.

+1

Используйте '' __import__' где вы хотите импортировать модуль, имя которого известно лишь в runtime'. Помимо этого ...как вы сказали, это дает вам больше мощности по сравнению с импортом. –

+0

Если память обслуживается правильно, видеоролик David Beasely при импорте, в видео он упоминает, что WerkZeug перегрузил импорт по какой-то причине. – Carel

ответ

34

__import__ - низкоуровневая функция крюка, которая используется для импорта модулей; его можно использовать для импорта модуля динамически, указав имя модуля для импорта в качестве переменной, что-то, что вы не дадите оператору import.

importlib.import_module() - обертка вокруг этого крючка * для создания приятного API для функциональности; это очень недавнее дополнение к Python 2 и было более сфокусировано на Python 3. Кодовые базы, которые используют __import__, обычно делают это, потому что они хотят оставаться совместимыми со старыми версиями Python 2, например. ничего перед Python 2.7.

Одним из побочных эффектов использования __import__ может быть то, что он возвращает импортированный модуль и ничего не добавляет к пространству имен; вы можете импортировать с ним, не имея затем удалить новое имя, если вы не хотите, чтобы это новое имя; используя import somename, добавьте somename в ваше пространство имен, но вместо этого возвращает __import__('somename') импортированный модуль, который вы можете игнорировать. По этой причине Werkzeug использует крючок в одном месте.

Все остальные виды использования относятся к динамическому импорту. Werkzeug поддерживает Python 2.6, поэтому он не может использовать importlib.


*importlib является реализация Pure-Python, и import_module() будет использовать эту реализацию, вист __import__ будет использовать C-оптимизированный вариант. Обе версии обращаются к importlib._bootstrap._find_and_load(), поэтому разница в основном академическая.

+0

Я не совсем понимаю, что вы подразумеваете под «вы можете импортировать с ним, не имея затем удалить новое имя, если вы не хотите, чтобы это новое имя». Если у вас есть минута, возможно, вы можете это сделать, как если бы вы разговаривали с малышами? – Aerovistae

+0

@Aerovistae: обновил это немного; 'import sys' добавляет имя' sys' в ваше пространство имен (привязанное к модулю), '__import __ ('sys')' возвращает объект модуля 'sys' вызывающему, который затем может игнорировать этот объект. –

+0

@MartijnPieters По пространству имен вы имеете в виду 'sys.modules'? – NeoWang

3

__import__(import_name), так что я не понимаю, как это не отличается от только с помощью оператора импорта

Оба __import__() и importlib.import_module() позволит вам импортировать модуль, когда у вас есть модуль имя в виде строки. Вы не можете написать:

x = 're' 
import x 

или вы получите:

File "1.py", line 3, in <module> 
import x ImportError: No module named x