При написании проектов на Python мы часто можем столкнуться с ошибками, из-за которых не удается импортировать модули:ImportError: No module named 'xxx'
илиModuleNotFoundError: No module named 'xxx'
.
Проблема сбоя импорта обычно делится на два типа: один — импорт модуля, написанного вами (то есть файла с суффиксом .py), а другой — импорт сторонней библиотеки. В этой статье в основном обсуждается вторая ситуация, и мы подробно обсудим другие связанные темы в будущем.
Чтобы решить проблему невозможности импорта библиотек Python, необходимо установить отсутствующую библиотеку в среде выполнения (обратите внимание, является ли это виртуальной средой) или использовать соответствующую альтернативу. Эта проблема делится на три случая:
1. Библиотеки отсутствуют в одном модуле
При написании кода, если нам нужно использовать стороннюю библиотеку (например, запросы), но мы не уверены, установлена ли она в реальной рабочей среде, мы можем написать это так:
try:
import requests
except ImportError:
import os
os.system('pip install requests')
import requests
Результатом этого является то, что если библиотека запросов не найдена, она будет сначала установлена, а затем импортирована.
В некоторых проектах с открытым исходным кодом мы также можем увидеть следующую запись (на примере json):
try:
import simplejson as json
except ImportError:
import json
В результате сначала импортируется сторонняя библиотека simplejson.Если ее не удается найти, используйте встроенную стандартную библиотеку json.
Преимущество такого способа написания состоит в том, что нет необходимости импортировать дополнительные библиотеки, но его недостаток состоит в том, что две библиотеки должны быть гарантированно совместимы при использовании.Если в стандартной библиотеке нет альтернативной библиотеки, то она не осуществимо. .
Если вы действительно не можете найти совместимую стандартную библиотеку, вы также можете сами написать модуль (например, my_json.py), реализовать то, что хотите, а затем импортировать его в операторе exclude.
try:
import simplejson as json
except ImportError:
import my_json as json
2. Библиотеки отсутствуют во всем проекте
Вышеупомянутая идея нацелена на разрабатываемый проект, но имеет ряд недостатков: 1. Нецелесообразно pip устанавливать в коде все возможные отсутствующие сторонние библиотеки 2. Определенная сторонняя библиотека не может быть использована разработчиком. стандартная библиотека или сама.Ручная замена библиотеки, что делать? 3. Что делать, если эти модификации не разрешены для уже сформированного проекта?
Так вот вопрос:Есть проект, который я хочу развернуть на новой машине. В нем задействовано множество сторонних библиотек, но ни одна из них не предустановлена на машине. Что мне делать?
Для совместимого проекта по соглашению он обычно содержит "requirements.txt", который записывает все зависимые библиотеки проекта и их требуемые номера версий. Это делается до того, как проект будет выпущен, с помощью командыpip freeze > requirements.txt
Сгенерировано.
использовать командуpip install -r requirements.txt
(Выполнить в каталоге, где находится файл, или прописать путь полного файла в команде), все зависимые библиотеки могут быть установлены автоматически.
Но что, если проект не соответствует требованиям или по какой-то другой неблагоприятной причине у нас нет такой документации?
Глупый способ - запустить проект, дождаться, когда он пойдет не так, и столкнуться с ошибкой библиотеки, установить ее вручную, затем снова запустить проект и установить его, когда библиотека выйдет из строя, и так далее... (1 здесь опущен 10 000 нецензурных слов) …
3. Автоматически импортировать все недостающие библиотеки
Есть ли лучший способ автоматически импортировать отсутствующие библиотеки?
Есть ли способ автоматически импортировать необходимые библиотеки без изменения исходного кода и без необходимости в файле «requirements.txt»?
Конечно, есть! Первый взгляд на эффект:
Давайте возьмем торнадо в качестве примера.На первом этапе мы видим, что мы не установили торнадо.После второго шага, когда мы снова импортируем торнадо, программа автоматически загрузит и установит торнадо для нас, поэтому об ошибке не будет сообщено. .
autoinstall — наш рукописный модуль, код такой:
# 以下代码在 python 3.6.1 版本验证通过
import sys
import os
from importlib import import_module
class AutoInstall():
_loaded = set()
@classmethod
def find_spec(cls, name, path, target=None):
if path is None and name not in cls._loaded:
cls._loaded.add(name)
print("Installing", name)
try:
result = os.system('pip install {}'.format(name))
if result == 0:
return import_module(name)
except Exception as e:
print("Failed", e)
return None
sys.meta_path.append(AutoInstall)
используется в этом кодеsys.meta_path
, давайте сначала распечатаем и посмотрим, что это такое?
Механизм импорта Python 3 примерно в следующем порядке в процессе поиска:
- Посмотрите в sys.modules, он кэширует все импортированные модули.
- Посмотрите в sys.meta_path, он поддерживает пользовательские загрузчики
- Посмотрите в sys.path, в котором записано имя каталога, в котором расположены некоторые библиотеки.
- Выбрасывает, если не найден
ImportError
аномальный
Среди них обратите внимание на sys.metaпуть отличается в разных версиях Python, например, он сильно отличается в Python 2 и Python 3; в более новых версиях Python 3 (3.4+) пользовательский загрузчик должен реализовать `findspec 方法,而早期的版本用的则是
найти_модуль`.
Приведенный выше код представляет собой пользовательский загрузчик библиотеки классов AutoInstall, который может автоматически импортировать стороннюю библиотеку. Следует отметить, что этот метод «захватит» все вновь импортированные библиотеки и уничтожит исходный метод импорта, поэтому могут возникнуть некоторые странные проблемы, обратите внимание.
sys.meta_path — это приложение зондов Python. Зонды, `import hook`, являются малоизвестным механизмом Python, но они могут делать много вещей, например загружать библиотеки по сети, модифицировать модули по мере их импорта, автоматически устанавливать отсутствующие библиотеки, загружать информацию аудита, ленивую загрузку и т. д.
Из-за ограниченности места мы не будем подробно его раскрывать. Наконец, резюме:
- Простой импорт или замену сторонних библиотек можно выполнить с помощью try...except
- Когда известны все отсутствующие зависимости (например, requirements.txt), вы можете установить их вручную.
- Используя sys.meta_path, можно автоматически импортировать произвольные отсутствующие библиотеки.
Использованная литература:
блог Air Shipping Talent/2016/10/25/…
docs.Python.org/3/library/… — это…
публика【Питон кот], в этом выпуске публикуется серия высококачественных статей, в том числе серия Meow Star Philosophy Cat, расширенная серия Python, серия рекомендаций по хорошим книгам, технические статьи, высококачественные рекомендации и перевод на английский язык и т. д. Добро пожаловать, обратите внимание.