Модулем в Python называется любой файл с программой (да-да, все те программы, которые вы писали, можно назвать модулями). В этой статье мы поговорим о том, как создать модуль, и как подключить модуль, из стандартной библиотеки или написанный вами.
Каждая программа может импортировать модуль и получить доступ к его классам, функциям и объектам. Нужно заметить, что модуль может быть написан не только на Python, а например, на C или C++.
Подключение модуля из стандартной библиотеки
Подключить модуль можно с помощью инструкции import. К примеру, подключим модуль os для получения текущей директории:
>>> import os >>> os.getcwd() ‘C:\Python33’
После ключевого слова import указывается название модуля. Одной инструкцией можно подключить несколько модулей, хотя этого не рекомендуется делать, так как это снижает читаемость кода. Импортируем модули time и random.
55 Установка модулей в Python || Установка пакета Python || Установка библиотеки в python
>>> import time, random >>> time.time() 1376047104.056417 >>> random.random() 0.9874550833306869
После импортирования модуля его название становится переменной, через которую можно получить доступ к атрибутам модуля. Например, можно обратиться к константе e, расположенной в модуле math:
>>> import math >>> math.e 2.718281828459045
Стоит отметить, что если указанный атрибут модуля не будет найден, возбудится исключение AttributeError. А если не удастся найти модуль для импортирования, то ImportError.
>>> import notexist Traceback (most recent call last): File «», line 1, in import notexist ImportError: No module named ‘notexist’ >>> import math >>> math.Ё Traceback (most recent call last): File «», line 1, in math.Ё AttributeError: ‘module’ object has no attribute ‘Ё’
Использование псевдонимов
Если название модуля слишком длинное, или оно вам не нравится по каким-то другим причинам, то для него можно создать псевдоним, с помощью ключевого слова as.
>>> import math as m >>> m.e 2.718281828459045
Теперь доступ ко всем атрибутам модуля math осуществляется только с помощью переменной m, а переменной math в этой программе уже не будет (если, конечно, вы после этого не напишете import math, тогда модуль будет доступен как под именем m, так и под именем math).
Инструкция from
Подключить определенные атрибуты модуля можно с помощью инструкции from. Она имеет несколько форматов:
from import [ as ], [ [ as ] . ] from import *
Первый формат позволяет подключить из модуля только указанные вами атрибуты. Для длинных имен также можно назначить псевдоним, указав его после ключевого слова as.
>>> from math import e, ceil as c >>> e 2.718281828459045 >>> c(4.6) 5
Импортируемые атрибуты можно разместить на нескольких строках, если их много, для лучшей читаемости кода:
Импорт собственных модулей в Python. Import modules. Атрибут модуля __name__ и __main__
>>> from math import (sin, cos, . tan, atan)
Второй формат инструкции from позволяет подключить все (точнее, почти все) переменные из модуля. Для примера импортируем все атрибуты из модуля sys:
>>> from sys import * >>> version ‘3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]’ >>> version_info sys.version_info(major=3, minor=3, micro=2, releaselevel=’final’, serial=0)
Следует заметить, что не все атрибуты будут импортированы. Если в модуле определена переменная __all__ (список атрибутов, которые могут быть подключены), то будут подключены только атрибуты из этого списка. Если переменная __all__ не определена, то будут подключены все атрибуты, не начинающиеся с нижнего подчёркивания. Кроме того, необходимо учитывать, что импортирование всех атрибутов из модуля может нарушить пространство имен главной программы, так как переменные, имеющие одинаковые имена, будут перезаписаны.
Создание своего модуля на Python
Теперь пришло время создать свой модуль. Создадим файл mymodule.py, в которой определим какие-нибудь функции:
def hello(): print(‘Hello, world!’) def fib(n): a = b = 1 for i in range(n — 2): a, b = b, a + b return b
Теперь в этой же папке создадим другой файл, например, main.py:
import mymodule mymodule.hello() print(mymodule.fib(10))
Hello, world! 55
Поздравляю! Вы сделали свой модуль! Напоследок отвечу ещё на пару вопросов, связанных с созданием модулей:
Как назвать модуль?
Помните, что вы (или другие люди) будут его импортировать и использовать в качестве переменной. Модуль нельзя именовать также, как и ключевое слово (их список можно посмотреть тут). Также имена модулей нельзя начинать с цифры. И не стоит называть модуль также, как какую-либо из встроенных функций. То есть, конечно, можно, но это создаст большие неудобства при его последующем использовании.
Куда поместить модуль?
Туда, где его потом можно будет найти. Пути поиска модулей указаны в переменной sys.path. В него включены текущая директория (то есть модуль можно оставить в папке с основной программой), а также директории, в которых установлен python. Кроме того, переменную sys.path можно изменять вручную, что позволяет положить модуль в любое удобное для вас место (главное, не забыть в главной программе модифицировать sys.path).
Можно ли использовать модуль как самостоятельную программу?
Можно. Однако надо помнить, что при импортировании модуля его код выполняется полностью, то есть, если программа что-то печатает, то при её импортировании это будет напечатано. Этого можно избежать, если проверять, запущен ли скрипт как программа, или импортирован. Это можно сделать с помощью переменной __name__, которая определена в любой программе, и равна «__main__», если скрипт запущен в качестве главной программы, и имя, если он импортирован. Например, mymodule.py может выглядеть вот так:
def hello(): print(‘Hello, world!’) def fib(n): a = b = 1 for i in range(n — 2): a, b = b, a + b return b if __name__ == «__main__»: hello() for i in range(10): print(fib(i))
Источник: pythoshka.ru
Как импортировать в Python?
Сегодня мы поговорим о том, как импортировать пакеты и модули в Python (а заодно и о разнице между ними). К концу руководства вы получите структуру каталогов (для проекта Medium_Imports_Tutorial), где будет удобно импортировать любые скрипты из одного подкаталога в другой (стрелки синего цвета на картинке ниже).
Примечание. Если вы хотите поиграться с кодом, то вот репозиторий Github.
Итак, наша структура каталогов для изучения импорта в Python будет выглядеть следующим образом:
Прежде чем начать, давайте обсудим, в чем разница между пакетом и модулем, так как мы будем опираться на эти понятия на протяжении всей статьи.
- Модуль — один скрипт Python.
- Пакет — набор модулей.
Вот и вся разница! Просто, не правда ли?
Что ж, теперь давайте начинать!
Импорт в рамках одного каталога
Структура каталогов на изображении выше выглядит немного сложной, но мы не будем создавать ее всю сразу.
Для простоты давайте сначала создадим один каталог scripts в каталоге нашего проекта и добавим в него два модуля — example1.py и example2.py . Наша структура будет выглядеть так:
Идея состоит в том, чтобы любая функция/переменная/класс, определенные в example1.py , были доступны в example2.py . Содержимое у нас будет таким:
#example1.py MY_EX1_STRING = ‘Welcome to Example1 module!’ def yolo(x: int): print(«You only LIve», x, «times.»)
Чтобы импортировать эти элементы в example2.py , сделаем следующее:
#example2.py import example1 # imported string print(«The imported string is: «, example1.MY_EX1_STRING) # imported function example1.yolo(10)
Как видно, доступ к элементам в импортированном модуле можно получить с помощью записи через точку — например, example1.yolo() или example1.MY_EX1_STRING . Если вам покажется, что каждый раз писать example1.XXX утомительно, можно воспользоваться псевдонимом (созданным при помощи as ) и переписать example2.py следующим образом:
#example2.py import example1 as e1 # imported string print(«The imported string is: «, e1.MY_EX1_STRING) # imported function e1.yolo(10)
Как вы правильно догадались, вывод останется прежним.
Но что именно происходит, когда мы пишем оператор import ?
Интерпретатор Python пытается найти в sys.path каталог с модулем, который мы пытаемся импортировать. sys.path — это список каталогов, в которых Python будет искать после просмотра кэшированных модулей и модулей стандартной библиотеки Python.
Давайте посмотрим, что в данный момент содержит наш системный путь sys.path (предварительно закомментировав предыдущие строки кода в example2.py ).
#example2.py # import example1 # print(«The imported string is: «, example1.MY_EX1_STRING) # example1.yolo(10) import sys print(sys.path)
Как видите, самый первый элемент в полученном списке sys.path указывает на каталог Medium_Imports_Tutorial/scripts , в котором находится наш импортированный модуль, т. е. example1.py . Имейте в виду: то, что этот каталог волшебным образом присутствует в sys.path , не случайно.
Вывод из sys.path всегда будет содержать текущий каталог с индексом 0! Текущий каталог — это тот, в котором находится запускаемый скрипт.
Поэтому, когда и вызывающий, и вызываемый модули находятся в одном каталоге, импорт довольно прост.
Что делать, если нужно импортировать только определенные элементы из модуля?
В нашем примере в модуле example1.py определены только переменная типа string и функция. Важно помнить, что всякий раз, когда выполняется оператор импорта, будет запущен весь модуль. Чтобы доказать это, давайте немного изменим example1.py :
#example1.py print(«Thanks for importing Example1 module.») MY_EX1_STRING = ‘Welcome to Example1 module!’ def yolo(x: int): print(«You only LIve», x, «times.») yolo(10000)
А теперь попробуйте запустить example2.py . Вы увидите, что вместе с выводом оператора print() также выведется yolo(10000) .
Примечание. Существует обходной путь, с помощью которого мы можем контролировать, будет ли оператор выполняться при импорте.
#example1.py print(«Thanks for importing Example1 module.») MY_EX1_STRING = ‘Welcome to Example1 module!’ def yolo(x: int): print(«You only LIve», x, «times.») if __name__ == ‘__main__’: yolo(10000)
Код внутри оператора if__name__ == ‘__main__’ не будет выполняться при импорте, но yolo() и MY_EX1_STRING , определенные снаружи, готовы к использованию через импорт. При этом, если бы мы запустили example1.py как автономный модуль, код внутри оператора if был бы выполнен.
Итак, мы увидели, что импорт модуля запускает все его содержимое (если не использовать if __name__ == «__main__» ). Теперь должно быть довольно понятно, почему импорт только интересующих элементов имеет смысл. Давайте посмотрим, как это сделать в example2.py . Для этого импортируем из example1.py только функцию yolo() . Это также поможет нам избавиться от записи через точку, и мы сможем просто использовать функцию yolo() .
#example2.py from example1 import yolo yolo(10)
Точно так же мы могли бы написать from example1 import yolo, MY_EX1_STRING , чтобы импортировать оба объекта из example1.py .
Примечание. В коде часто можно увидеть такие импорты, как from example1 import * . По сути, это означает импорт всего. Но это считается плохой практикой, поскольку негативно влияет на читабельность кода.
Зачем нужен PYTHONPATH?
Возможно, вы замечали, что в структуре каталогов проектов на GitHub часто бывает каталог utils . Он содержит служебные скрипты для распространенных задач, таких как предварительная обработка и очистка данных. Они хранятся отдельно от основных сценариев и предназначены для многократного использования.
Давайте создадим такой каталог для нашего проекта.
Пакет utils будет содержать три модуля — length.py , lower.py и upper.py для возврата длины строки и строк в нижнем и верхнем регистре соответственно.
Также создадим модуль example3_outer.py в корне проекта. Сюда мы будем импортировать модули из пакета util s.
Содержимое трех модулей будет следующим:
#utils/length.py def get_length(name: str): return len(name) #utils/lower.py def to_lower(name: str): return name.lower() #utils/upper.py def to_upper(name: str): return name.upper()
Теперь, чтобы импортировать модуль length.py в example3_outer.py , пишем следующее:
#example3_outer.py import utils.length res = utils.length.get_length(«Hello») print(«The length of the string is: «,res)
Важно отметить, что если бы мы выполнили импорт length вместо импорта utils.length , мы получили бы ModuleNotFoundError: No module named ‘length’ . Это связано с тем, что список sys.path пока не содержит каталога ../Medium_Imports_Tutorial/utils , который необходим для поиска модуля length.py . Давайте посмотрим, как мы можем добавить его в этот список.
Есть два способа сделать это.
Способ 1: использование sys.path.append
#example3_outer.py import os import sys fpath = os.path.join(os.path.dirname(__file__), ‘utils’) sys.path.append(fpath) print(sys.path) import length txt = «Hello» res_len = length.get_length(txt) print(«The length of the string is: «,res_len)
Несколько вещей, которые следует учесть:
1. Порядок импорта важен. Мы сможем выполнить import length только после добавления пути к каталогу utils с помощью sys.path.append .
Короче говоря, не поддавайтесь искушению объединить import os , import sys и import length в верхней части скрипта только для аккуратности!
2. os.path.dirname(__file__) возвращает абсолютный путь к текущему рабочему каталогу. Мы используем os.path.join , чтобы добавить каталог utils к этому пути.
3. Как всегда, доступ к функциям, определенным в импортированном модуле, упрощается с помощью записи через точку, т.е. length.get_length() .
Способ 2: использование переменной окружения PYTHONPATH
Однако зачастую проще изменить переменную PYTHONPATH , чем возиться с добавлением каталогов, как мы это только что делали.
PYTHONPATH — это переменная среды, которую вы можете настроить для добавления дополнительных каталогов, в которых Python будет искать модули и пакеты.
Прежде чем изменить PYTHONPATH , давайте проверим его содержимое при помощи команды echo $PYTHONPATH в терминале (чтобы случайно не перезаписать):
Похоже, сейчас PYTHONPATH пуст, но если это не так, лучше изменять его путем дополнения, а не перезаписи. Для этого нужно добавлять новый каталог в PYTHONPATH , отделяя его двоеточием от существующего содержимого.
С установленной переменной PYTHONPATH нам больше не нужно добавлять каталог к sys.path в example3_outer.py (мы закомментировали этот код в приведенном ниже фрагменте для ясности).
#example3_outer.py #import os #import sys #fpath = os.path.join(os.path.dirname(__file__), ‘utils’) #sys.path.append(fpath) #print(sys.path) import length txt = «Hello» res_len = length.get_length(txt) print(«The length of the string is: «,res_len)
Примечание. Как только вы закроете python, список вернется к предыдущим значениям по умолчанию. Если вы хотите добавить каталог в PYTHONPATH навсегда, добавьте команду экспорта ( export PYTHONPATH=$PYTHONPATH:$(pwd)/utils ) в файл ~/.bashrc . (подробнее можно почитать обсуждение на StackOverflow).
Наконец, познакомившись с обоими методами, давайте выберем один (в зависимости от ваших предпочтений и нужд) для импорта оставшихся двух модулей — upper.py и lower.py в example3_outer.py .
P.S. Мы воспользуемся методом 1 просто для удовольствия
#example3_outer.py import os import sys fpath = os.path.join(os.path.dirname(__file__), ‘utils’) sys.path.append(fpath) import length import upper import lower txt = «Hello» res_len = length.get_length(txt) print(«The length of the string is: «,res_len) res_up = upper.to_upper(txt) print(«Uppercase txt: «, res_up) res_low = lower.to_lower(txt) print(«Uppercase txt: «, res_low)
Супер! Это выглядит потрясающе. Однако было бы здорово, если бы мы могли просто выполнить команду import utils вместо того, чтобы импортировать все модули по отдельности.
В конце концов, наш случай использования предполагает, что нам нужны все три функции. Итак, как это сделать?
Когда нам нужен __init__.py?
Во-первых, давайте попробуем импортировать каталог utils в файле example3_outer.py (предварительно закомментировав весь существующий код):
#example3_outer.py import utils
Запуск этого скрипта не вызовет никакой ошибки, и это правильно — интерпретатор заглянет внутрь sys.path и найдет текущий каталог ../Medium_Imports_Tutorial с индексом 0. Это все, что ему нужно, чтобы найти каталог utils .
Теперь попробуем получить доступ к модулю length.py из utils :
#example3_outer.py import utils txt = «Hello» res = utils.length.get_length(txt)
Попытавшись запустить этот скрипт, вы увидите AttributeError: module ‘utils’ has no attribute ‘length’ . Это означает, что мы не сможем получить доступ к каким-либо скриптам Python внутри utils просто потому, что интерпретатор еще не знает, что это пакет!
Модули
Модуль в языке Python представляет отдельный файл с кодом, который можно повторно использовать в других программах.
Для создания модуля необходимо создать собственно файл с расширением *.py , который будет представлять модуль. Название файла будет представлять название модуля. Затем в этом файле надо определить одну или несколько функций.
Допустим, основной файл программы называется main.py . И мы хотим подключить к нему внешние модули.
Для этого сначала определим новый модуль: создадим в той же папке, где находится main.py, новый файл, который назовем message.py . Если используется PyCharm или другая IDE, то оба файла просто помещаются в один проект.
Соответственно модуль будет называться message . Определим в нем следующий код:
hello = «Hello all» def print_message(text): print(f»Message: «)
Здесь определена переменная hello и функция print_message, которая в качестве параметра получает некоторый текст и выводит его на консоль.
В основном файле программы — main.py используем данный модуль:
import message # подключаем модуль message # выводим значение переменной hello print(message.hello) # Hello all # обращаемся к функии print_message message.print_message(«Hello work») # Message: Hello work
Для использования модуля его надо импортировать с помощью оператора import , после которого указывается имя модуля: import message .
Чтобы обращаться к функциональности модуля, нам нужно получить его пространство имен . По умолчанию оно будет совпадать с именем модуля, то есть в нашем случае также будет называться message .
Получив пространство имен модуля, мы сможем обратиться к его функциям по схеме
Например, обращение к функции print_message() из модуля message:
message.print_message(«Hello work»)
И после этого мы можем запустить главный скрипт main.py, и он задействует модуль message.py. В частности, консольный вывод будет следующим:
Hello all Message: Hello work
Подключение функциональности модуля в глобальное пространство имен
Другой вариант настройки предполагает импорт функциональности модуля в глобальное пространство имен текущего модуля с помощью ключевого слова from :
from message import print_message # обращаемся к функии print_message из модуля message print_message(«Hello work») # Message: Hello work # переменная hello из модуля message не доступна, так как она не импортирована # print(message.hello) # print(hello)
В данном случае мы импортируем из модуля message в глобальное пространство имен функцию print_message() . Поэтому мы сможем ее использовать без указания пространства имен модуля как если бы она была определена в этом же файле.
Все остальные функции, переменные из модуля недоступны (как например, в примере выше переменная hello). Если мы хотим их также использовать, то их можно подключить по отдельности:
from message import print_message from message import hello # обращаемся к функции print_message из модуля message print_message(«Hello work») # Message: Hello work # обращаемся к переменной hello из модуля message print(hello) # Hello all
Если необходимо импортировать в глобальное пространство имен весь функционал, то вместо названий отдельных функций и переменных можно использовать символ зводочки * :
from message import * # обращаемся к функции print_message из модуля message print_message(«Hello work») # Message: Hello work # обращаемся к переменной hello из модуля message print(hello) # Hello all
Но стоит отметить, что импорт в глобальное пространство имен чреват коллизиями имен функций. Например, если у нас том же файле определена функция с тем же именем до ее вызова, то будет вызываться функция, которая определена последней:
from message import * print_message(«Hello work») # Message: Hello work — применяется функция из модуля message def print_message(some_text): print(f»Text: «) print_message(«Hello work») # Text: Hello work — применяется функция из текущего файла
Таким образом, одноименная функция текущего файла скрывает функцию из подключенного модуля.
Установка псевдонимов
При импорте модуля и его функциональности мы можем установить для них псевдонимы. Для этого применяется ключевое слово as , после которого указывается псевдоним. Например, установим псевдоним для модуля:
import message as mes # модуль message проецируется на псевдоним mes # выводим значение переменной hello print(mes.hello) # Hello all # обращаемся к функии print_message mes.print_message(«Hello work») # Message: Hello work
В данном случае пространство имен будет называться mes , и через этот псевдоним можно обращаться к функциональности модуля.
Подобным образом можно установить псевдонимы для отдельной функциональности модуля:
from message import print_message as display from message import hello as welcome print(welcome) # Hello all — переменная hello из модуля message display(«Hello work») # Message: Hello work — функция print_message из модуля message
Здесь для функции print_message из модуля message устанавливается псевдоним display, а для переменной hello — псевдоним welcome. И через эти псевдонимы мы сможем к ним обращаться.
Псевдонимы могут быть полезны, когда нас не устраивают имена функций и переменных, например, они слишком длинные, и мы хотим их сократить, либо мы хотим дать им более описательные, с нашей точки зрения, имена. Либо если в текущем файле уже есть функциональность с теми же именами, и с помощью установки псевдонимов мы можем избежать конфликта имен. Например:
from message import print_message as display def print_message(some_text): print(f»Text: «) # функция print_message из модуля message display(«Hello work») # Message: Hello work # функция print_message из текущего файла print_message(«Hello work») # Text: Hello work
Имя модуля
В примере выше модуль main.py, который является главным, использует модуль message.py. При запуске модуля main.py программа выполнит всю необходимую работу.
Однако, если мы запустим отдельно модуль message.py сам по себе, то ничего на консоли не увидим. Ведь модуль message просто определяет функцию и переменную и не выполняет никаких других действий. Но мы можем сделать так, чтобы модуль message.py мог использоваться как сам по себе, так и подключаться в другие модули.
При выполнении модуля среда определяет его имя и присваивает его глобальной переменной __name__ (с обеих сторон по два подчеркивания). Если модуль является запускаемым, то его имя равно __main__ (также по два подчеркивания с каждой стороны). Если модуль используется в другом модуле, то в момент выполнения его имя аналогично названию файла без расширения py. И мы можем это использовать. Так, изменим содержимое файла message.py :
hello = «Hello all» def print_message(text): print(f»Message: «) def main(): print_message(hello) if __name__ == «__main__»: main()
В данном случае в модуль message.py для тестирования функциональности модуля добавлена функция main . И мы можем сразу запустить файл message.py отдельно от всех и протестировать код.
Следует обратить внимание на вызов функции main:
if __name__ == «__main__»: main()
Переменная __name__ указывает на имя модуля. Для главного модуля, который непосредственно запускается, эта переменная всегда будет иметь значение __main__ вне зависимости от имени файла.
Поэтому, если мы будем запускать скрипт message.py отдельно, сам по себе, то Python присвоит переменной __name__ значение __main__ , далее в выражении if вызовет функцию main из этого же файла.
Однако если мы будем запускать другой скрипт, а этот — message.py — будем подключать в качестве вспомогательного, для message.py переменная __name__ будет иметь значение message . И соответственно метод main в файле message.py не будет работать.