Импорт модулей в Python 2: полное руководство
Основные техники импорта в Python 2
Наиболее эффективное решение для написания переносимого кода.
В Python 2 основным способом импорта является инструкция import. Для обеспечения совместимости с Python 3 рекомендуется использовать from __future__ import absolute_import. Это позволяет отключить неявный относительный импорт и сделать поведение импорта таким же, как в Python 3.
# file: mylib/mymod.py
from __future__ import absolute_import
import os # абсолютный импорт
print(os.name)Python 2 import (импорт в python 2)
posix # пример вывода
программы на python 2 (программы на python 2)
Этот подход упрощает переход на Python 3 и предотвращает ошибки, когда локальный модуль случайно перекрывает стандартный.
Как выполнить абсолютный импорт без побочных эффектов?
Использование from __future__ import absolute_import в начале файла переключает интерпретатор в режим абсолютного импорта, аналогичный Python 3. Без этой директивы Python 2 прежде всего ищет модуль в пакете (относительно текущего файла), а затем в sys.path.
# без __future__
import string # может импортировать локальный string.pyPython 3 программы (программы на python 3)
Проблема:
Неожиданные результаты, если в текущем каталоге есть файл с именем, совпадающим со стандартным модулем. Решение: использовать from __future__ import absolute_import или явно указывать полный путь через sys.path.insert().
Как импортировать модуль с помощью псевдонима?
Для сокращения имени или избежания конфликтов используется import module as alias.
import numpy as np
print(np.array([1,2,3]))Python 2 print (print в python 2)
[1 2 3]
Install python 64 bit (установка python 64-bit)
Как импортировать только определённые имена из модуля?
Используется from module import name1, name2. Это добавляет имена в текущее пространство имён.
from math import pi, sqrt
print(pi, sqrt(4))3.14159265359 2.0
Как организовать относительный импорт внутри пакета?
В Python 2 относительный импорт выполняется с помощью точки .:
# file: package/submodule.py
from . import sibling # импорт sibling из текущего пакета
from .. import parent # импорт из родительского пакетаНо такая форма может работать непредсказуемо при отсутствии __future__ import absolute_import. Рекомендуется всегда включать эту директиву.
Типичная ошибка:
ImportError: No module named ... при попытке относительного импорта из скрипта, запущенного напрямую. Решение: выполнять скрипт как модуль (python -m package.module) или использовать абсолютные пути.
Как импортировать все имена из модуля?
Используется from module import *. Такой импорт загрязняет пространство имён и скрывает, какие имена используются, поэтому его следует избегать, за исключением особых случаев (например, в пакетах для реэкспорта).
from os import *
print(getcwd())Проблема:
Неявное переопределение имён, сложность отладки. Решение: заменить на явные импорты или определить __all__ в модуле.
Как управлять порядком поиска модулей?
Список путей поиска хранится в sys.path. Можно добавлять свои пути:
import sys
sys.path.insert(0, '/my/custom/path')
import custommoduleОшибка:
Import конфликты при добавлении путей. Решение: добавлять пути в конец списка, чтобы не перекрывать стандартные модули.
Расширенные примеры импорта в Python 2
Импорт с переименованием для устранения конфликтов
# Файл mymodule.py
def foo():
print('foo')
# Основной скрипт
import mymodule as mm
import othermodule as mm # конфликт, но последний заменит
mm.foo() # вызовет othermodule.foo()Traceback (most recent call last): File "", line 1, in AttributeError: 'module' object has no attribute 'foo'
Конфликты псевдонимов приводят к потере доступа. Рекомендуется давать уникальные псевдонимы.
Импорт из __future__ для совместимости
from __future__ import division, print_function
print(5/2) # в Python 2 без деления с плавающей точкой будет 22.5
Директива division меняет поведение оператора / на деление с плавающей точкой, как в Python 3.
Относительный импорт в пакете с __init__.py
# Структура:
# package/
# __init__.py
# module_a.py
# sub/
# __init__.py
# module_b.py
# module_b.py
from __future__ import absolute_import
from . import module_a # относительный импорт
print(module_a.some_variable)
# Запуск: python -m package.sub.module_bЕсли запустить python package/sub/module_b.py, возникнет ошибка ValueError: Attempted relative import in non-package. Решение: запускать с флагом -m.
Импорт с проверкой версии Python
import sys
if sys.version_info[0] < 3:
from urllib2 import urlopen
else:
from urllib.request import urlopen
# Теперь urlopen работает в обеих версияхТакой подход помогает писать код, работающий в Python 2 и 3, без дополнительных библиотек.
Использование __all__ для контроля импорта *
# module.py
__all__ = ['public_func', 'public_class']
def public_func():
pass
def _private_func():
pass
# основной файл
from module import *
public_func() # работает
_private_func() # NameErrorNameError: name '_private_func' is not defined
Список __all__ ограничивает множество имён, импортируемых через *. Это улучшает структуру кода.
Динамический импорт с помощью __import__
module_name = 'os'
mod = __import__(module_name)
print(mod.getcwd())/home/user/project
Функция __import__ позволяет импортировать модуль, чьё имя задаётся строкой. Используется осторожно из-за потери проверок на этапе компиляции.
Импорт модулей из zip-архивов
import sys
sys.path.insert(0, '/path/to/archive.zip')
import module_in_zipPython 2 умеет импортировать модули прямо из zip-файлов, что полезно для распространения приложений как единого пакета.