Импорт модулей в Python 2: полное руководство

Раздел: Python -> Версии Python

Основные техники импорта в 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.py

Python 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 без деления с плавающей точкой будет 2
2.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()  # NameError
NameError: 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_zip

Python 2 умеет импортировать модули прямо из zip-файлов, что полезно для распространения приложений как единого пакета.

Импорт в Python 2 - comments

En
Python 2 import (python)