Python windows import module

Как работают импорты в Python

Порой бывает трудно правильно реализовать import с первого раза, особенно если мы хотим добиться правильной работы на плохо совместимых между собой версиях Python 2 и Python 3. Попытаемся разобраться, что из себя представляют импорты в Python и как написать решение, которое подойдёт под обе версии языка.

Содержание

Ключевые моменты

  • Выражения import производят поиск по списку путей в sys.path .
  • sys.path всегда включает в себя путь скрипта, запущенного из командной строки, и не зависит от текущей рабочей директории.
  • Импортирование пакета по сути равноценно импортированию __init__.py этого пакета.

Основные определения

  • Модуль: любой файл *.py . Имя модуля — имя этого файла.
  • Встроенный модуль: «модуль», который был написан на Си, скомпилирован и встроен в интерпретатор Python, и потому не имеет файла *.py .
  • Пакет: любая папка, которая содержит файл __init__.py . Имя пакета — имя папки.
    • С версии Python 3.3 любая папка (даже без __init__.py ) считается пакетом.
  • Объект: в Python почти всё является объектом — функции, классы, переменные и т. д.

Пример структуры директорий

Обратите внимание, что в корневой папке test/ нет файла __init__.py .

Что делает import

При импорте модуля Python выполняет весь код в нём. При импорте пакета Python выполняет код в файле пакета __init__.py , если такой имеется. Все объекты, определённые в модуле или __init__.py , становятся доступны импортирующему.

Основы import и sys.path

Вот как оператор import производит поиск нужного модуля или пакета согласно документации Python:

При импорте модуля spam интерпретатор сначала ищёт встроенный модуль с таким именем. Если такого модуля нет, то идёт поиск файла spam.py в списке директорий, определённых в переменной sys.path . sys.path инициализируется из следующих мест:

  • директории, содержащей исходный скрипт (или текущей директории, если файл не указан);
  • директории по умолчанию, которая зависит от дистрибутива Python;
  • PYTHONPATH (список имён директорий; имеет синтаксис, аналогичный переменной окружения PATH ).

Программы могут изменять переменную sys.path после её инициализации. Директория, содержащая запускаемый скрипт, помещается в начало поиска перед путём к стандартной библиотеке. Это значит, что скрипты в этой директории будут импортированы вместо модулей с такими же именами в стандартной библиотеке.

Технически документация не совсем полна. Интерпретатор будет искать не только файл (модуль) spam.py , но и папку (пакет) spam .

Обратите внимание, что Python сначала производит поиск среди встроенных модулей — тех, которые встроены непосредственно в интерпретатор. Список встроенных модулей зависит от дистрибутива Python, а найти этот список можно в sys.builtin_module_names (Python 2 и Python 3). Обычно в дистрибутивах есть модули sys (всегда включён в дистрибутив), math , itertools , time и прочие.

В отличие от встроенных модулей, которые при поиске проверяются первыми, остальные (не встроенные) модули стандартной библиотеки проверяются после директории запущенного скрипта. Это приводит к сбивающему с толку поведению: возможно «заменить» некоторые, но не все модули стандартной библиотеки. Допустим, модуль math является встроенным модулем, а random — нет. Таким образом, import math в start.py импортирует модуль из стандартной библиотеки, а не наш файл math.py из той же директории. В то же время, import random в start.py импортирует наш файл random.py .

Читайте также:  Что такое ati radeon hd 4600 series для windows

12–25 апреля, Онлайн, Беcплатно

Кроме того, импорты в Python регистрозависимы: import Spam и import spam — разные вещи.

Функцию pkgutil.iter_modules() (Python 2 и Python 3) можно использовать, чтобы получить список всех модулей, которые можно импортировать из заданного пути:

Чуть подробнее о sys.path

Чтобы увидеть содержимое sys.path , запустите этот код:

Документация Python описывает sys.path так:

Список строк, указывающих пути для поиска модулей. Инициализируется из переменной окружения PYTHONPATH и директории по умолчанию, которая зависит от дистрибутива Python.

При запуске программы после инициализации первым элементом этого списка, path[0] , будет директория, содержащая скрипт, который был использован для вызова интерпретатора Python. Если директория скрипта недоступна (например, если интерпретатор был вызван в интерактивном режиме или скрипт считывается из стандартного ввода), то path[0] является пустой строкой. Из-за этого Python сначала ищет модули в текущей директории. Обратите внимание, что директория скрипта вставляется перед путями, взятыми из PYTHONPATH .

Документация к интерфейсу командной строки Python добавляет информацию о запуске скриптов из командной строки. В частности, при запуске python

Создание и импорт модулей

На предыдущих занятиях мы с вами иногда подключали сторонние модули для расширения базовой функциональности языка Python. И делали это так:

то есть, писали ключевое слово import, после которого указывали название модуля:

или, можно сделать так:

Но что такое модуль? В самом простом случае – это набор конструкций языка Python, например, набор часто используемых функций. Так, подключая модуль math, мы получаем доступ к тригонометрическим функциям:

cos, sin, tan, и т.п.

И, потом можем вызвать их по следующему синтаксису:

В частности, так:

И при запуске увидим значение косинуса при угле в 0,7 радиан.

Но зачем нужны модули? Дело в том, что при создании крупных проектов стараются предельно упрощать процесс разработки программ. И один из методов здесь – это декомпозиция большой задачи на множество более мелких, которые, как правило, можно реализовать независимо друг от друга. Представьте, например, что нам нужно создать программу по распознаванию лиц и разработчики решили для этого использовать нейронную сеть. Тогда программу в целом можно (упрощенно) представить следующими модулями.

При этом каждый модуль может включать (подключать) другие вспомогательные модули, образуя сложную иерархическую архитектуру программы.

Кроме того, модули бывают полезны, когда предполагается часто использовать определенный функционал в своих проектах. Не случайно язык Python поставляется с набором стандартных модулей, таких как math, random, sys и другие. Они значительно облегчают разработку самых разных программ. Их полный набор можно посмотреть на сайте https://docs.python.org/3/library/ или выполнить поиск на ресурсе https://pypi.org.

Давайте теперь подробнее посмотрим как подключаются и создаются модули в Python. Начнем с того, что мы хотим создать свой собственный модуль. Для этого создадим файл в том же каталоге, что и файл ex1.py и назовем его

Содержимое этого файла будет состоять из одной константы и трех функций:

Все, наш модуль создан. Теперь подключим его в нашей программе:

Обратите внимание, мы указываем имя файла нашего модуля без расширения py. То есть, имя файла – это и есть имя модуля. Далее, вызовем из него функцию, допустим, sum:

Здесь мы указали сначала имя модуля, поставили точку и затем, имя функции. То же самое, если требуется обратиться к отдельной переменной:

Откуда появилось mymath и что это такое? В действительности, это так называемое, пространство имен, которое автоматически создается при подключении модуля. И в этом пространстве определены все функции и переменные, чтобы избежать возможных конфликтов с другими подобными функциями. Например, в Python уже существует функция sum, но наш вариант из модуля mymath никак не повлияет на ее работоспособность. Вот для этого и нужны пространства имен.

Читайте также:  Как установить atom mac os

Если же мы не хотим создавать нового пространства имен, то можно импортировать элементы модуля по следующему правилу:

В этом случае будет доступна только указанная функция sum модуля mymath. Причем, для ее использования уже не нужно писать название модуля, а просто вызвать ее по имени:

А вот другие элементы, например, переменная PI:

будет недоступна, т.к. не была импортирована. Если нужно импортировать таким образом несколько функций или переменных, то следует их перечислить через запятую:

или, для получения всего содержимого, записать звездочку:

Но, используя такой способ, можно столкнуться с конфликтом имен уже существующих переменных и функций с тем же именем. В нашем случае функция sum перекрывает стандартную функцию sum и прежняя уже недоступна. Чтобы такого не происходило можно указывать алиас (псевдоним) импортируемого элемента:

И к нашей функции мы можем теперь обратиться через этот алиас:

Или, записать так:

Тогда переменная PI доступна по своему имени, а функция sum по имени my_sum.

Во всех наших примерах модуль mymath находился в том же каталоге, что и файл ex1.py. И это было сделано не случайно. Когда мы что-либо импортируем, то файл ищется следующим образом:

  • в текущей директории программы (в данном случае ex1.py);
  • в директориях, указанных в переменной окружения PYTHONPATH;
  • в директориях стандартных библиотек;
  • в дополнительных путях, прописанные в .pth-файлах и пакетах сторонних разработчиков.

Если мы наш файл mymath.py поместим, например, в подкаталог lib, то при импорте указываем его следующим образом:

Если же импортируем непосредственно:

то будет сформировано пространство имен lib.mymath:

А теперь давайте посмотрим на особенности операции импорта. Предположим, что импортируем наш модуль

затем, меняем значение переменной:

и снова импортируем модуль:

выводим полученное значение:

и видим значение 3, а не 3,1415. Почему так произошло? Почему данные не обновились при повторном импорте? Дело в том, что Python в целях оптимизации импортирует каждый отдельный модуль только один раз и затем уже не меняет. Поэтому значение переменной PI осталось неизменным. Однако, модуль можно принудительно перезагрузить, используя вспомогательный модуль. В Python версии 3.4 и выше – это importlib:

Теперь, мы видим обновленное значение 3,1415.

Далее, когда мы импортируем данные с использованием from:

то они буквально копируются в глобальную область видимости нашей программы ex1.py. То есть, здесь идет создание новой переменной PI с соответствующим значением. В этом легко убедиться. Давайте импортируем модуль еще раз:

и изменим это значение:

выведем переменные в консоль:

Видите? Изменение переменной PI никак не затронуло переменную mymath.PI, т.к. это две совершенно разные переменные.

Но если подобную операцию выполнить с переменной, которая ссылается на изменяемый тип данных, например, список:

то ситуация кардинально меняется. Добавим этот список в наш модуль и запишем такую программу:

На выходе получаем одинаковые списки. Но если мы изменим один из них:

то это скажется и на изменении другого! То есть, изменяемые типы данных не копируются и обе переменные ar и mymath.ar ссылаются на один и тот же список.

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

Читайте также:  Download windows 10 pro x86

Это неизменяемый тип, следовательно, должны при импортах получать копии, проверим:

Да, теперь изменение одного не ведет к изменению другого. Вот этот момент с импортом данных следует иметь в виду.

Далее, в Python имеется полезная функция

которая возвращает имена всех данных, которые импортируются с указанным модулем. Например, вот такая программа:

Отобразит в консоли следующий список имен:

[‘PI’, ‘__builtins__’, ‘__cached__’, ‘__doc__’, ‘__file__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘ar’, ‘max2’, ‘max3’, ‘sum’]

Здесь помимо наших переменных PI, ar и функций max2, max3, sum имеется еще набор служебных переменных.

Задания для самоподготовки

1. Создайте модуль с двумя функциями, которые бы вычисляли периметр и площадь прямоугольника. Подключите этот модуль к основной программе и вызовите эти функции с аргументами, введенные с клавиатуры.

2. Задайте в модуле словарь, в котором ключами являются английские слова, а значениями соответствующие русские (переводы). Также добавьте необходимые функции для добавления и удаления новых слов в этом словаре. Импортируйте этот модуль в основную программу и реализуйте мини-словарь со следующим меню (функционалом):

1. Перевести слово
2. Добавить слово
3. Удалить слово
4. Завершить работу

Попробуйте развить идею словаря и добавьте возможность автоматического сохранения и считывания данных из файла (в файле сохраняется словарь целиком).

Видео по теме

Python 3 #1: установка и запуск интерпретатора языка

Python 3 #2: переменные, оператор присваивания, типы данных

Python 3 #3: функции input и print ввода/вывода

Python 3 #4: арифметические операторы: сложение, вычитание, умножение, деление, степень

Python 3 #5: условный оператор if, составные условия с and, or, not

Python 3 #6: операторы циклов while и for, операторы break и continue

Python 3 #7: строки — сравнения, срезы строк, базовые функции str, len, ord, in

Python 3 #8: методы строк — upper, split, join, find, strip, isalpha, isdigit и другие

Python 3 #9: списки list и функции len, min, max, sum, sorted

Python 3 #10: списки — срезы и методы: append, insert, pop, sort, index, count, reverse, clear

Python 3 #11: списки — инструмент list comprehensions, сортировка методом выбора

Python 3 #12: словарь, методы словарей: len, clear, get, setdefault, pop

Python 3 #13: кортежи (tuple) и операции с ними: len, del, count, index

Python 3 #14: функции (def) — объявление и вызов

Python 3 #15: делаем «Сапер», проектирование программ «сверху-вниз»

Python 3 #16: рекурсивные и лямбда-функции, функции с произвольным числом аргументов

Python 3 #17: алгоритм Евклида, принцип тестирования программ

Python 3 #18: области видимости переменных — global, nonlocal

Python 3 #19: множества (set) и операции над ними: вычитание, пересечение, объединение, сравнение

Python 3 #20: итераторы, выражения-генераторы, функции-генераторы, оператор yield

Python 3 #21: функции map, filter, zip

Python 3 #22: сортировка sort() и sorted(), сортировка по ключам

Python 3 #23: обработка исключений: try, except, finally, else

Python 3 #24: файлы — чтение и запись: open, read, write, seek, readline, dump, load, pickle

Python 3 #25: форматирование строк: метод format и F-строки

Python 3 #26: создание и импорт модулей — import, from, as, dir, reload

Python 3 #27: пакеты (package) — создание, импорт, установка (менеджер pip)

Python 3 #28: декораторы функций и замыкания

Python 3 #29: установка и порядок работы в PyCharm

Python 3 #30: функция enumerate, примеры использования

© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта

Оцените статью