#16 – Модули в языке Питон. Создание и работа с модулями
Основная мощь языка Питон раскрывается в момент использования дополнительных модулей. В ходе урока мы научимся подключать встроенные модули Python, научимся создавать свои собственные модули, а также ознакомитесь с подключением пакетов через встроенный менеджер «pip».
Видеоурок
Полезные ссылки:
Модули – это дополнительные файлы, что можно импортировать внутрь других файлов Python. Каждый модуль содержит набор переменных и функций, которые можно использовать после подключения модуля к какому-либо файлу.
Модули можно создавать свои или использовать уже готовые модули Python. С полным перечнем всех стандартных модулей вы можете ознакомиться по этой ссылке .
Все модули запомнить невозможно, а главное это не нужно. Вам необходимо лишь понимать какой модуль за что отвечает и в случае необходимости вы сможете подсмотреть документацию, которой в интернете полным полно. К примеру, вы хотите создать архив или добавить что-либо в уже существующий? Тогда вам понадобиться модуль ZipFile , который позволяет работать с архивами: создавать их, добавлять файлы, удалять файлы и делать другие вещи.
Таких модулей огромное множество и каждый отвечает за какие-либо функции и новшества.
Чтобы подключить модуль необходимо использовать команду import и указать название модуля.
import time # Импорт одного модуля import random, os # Импорт нескольких модулей
Также вы можете создавать свои модули. Для этого необходимо создать новый файл и по его названию подключать файл как модуль в другие файлы.
Команда From
Чтобы импортировать лишь некоторые методы или же переменные можно использовать команду from . Эта команда записывается следующим образом:
from math import ceil # Импортируем лишь метод ceil
Псевдонимы для модулей
Также при работе с модулями можно использовать псевдонимы. Это позволяет сократить название модуля, если оно слишком большое и вам не хочется писать его каждый раз.
import Template as tem # Теперь можно обращаться к модулю как tem
Модули Питон
import datetime as d, sys, os, platform from math import sqrt as s, ceil # print(d.datetime.now().time()) print(ceil(s(25)))
Свои модули
from mymodule import add_three_numbers as add print(add(5, 3, 0))
Посмотреть остальной код можно после подписки на проект!
Задание к уроку
Необходимо оформить подписку на проект, чтобы получить доступ ко всем домашним заданиям
Большое задание по курсу
Вам необходимо оформить подписку на сайте, чтобы иметь доступ ко всем большим заданиям. В задание входит методика решения, а также готовый проект с ответом к заданию.
PS: подобные задания доступны при подписке от 1 месяца
Модули
Основные модули в Python 3. Описание модулей и перевод документации к ним.
Модуль csv — чтение и запись CSV файлов
Формат CSV (Comma Separated Values) является одним из самых распространенных форматов импорта и экспорта электронных таблиц и баз данных. CSV использовался в течение многих лет до того, как был стандартизирован в RFC 4180. Запоздание четко определенного стандарта означает, что в данных, создаваемых различными приложениями, часто существуют незначительные различия. Эти различия могут вызвать раздражение при обработке файлов CSV из нескольких источников. Тем не менее, хотя разделители, символы кавычек и некоторые другие свойства различаются, общий формат достаточно универсален. Значит, возможно написать один модуль, который может эффективно манипулировать такими данными, скрывая детали чтения и записи данных от программиста.
Модуль shutil
Модуль shutil содержит набор функций высокого уровня для обработки файлов, групп файлов, и папок. В частности, доступные здесь функции позволяют копировать, перемещать и удалять файлы и папки. Часто используется вместе с модулем os.
Модуль unittest: тестируем свои программы
Представьте, что вы написали какую-либо программу, а теперь хотите проверить, правильно ли она работает. Что вы для этого сделаете? Скорее всего, вы запустите её несколько раз с различными входными данными, и убедитесь в правильности выдаваемого ответа.
А теперь вы что-то поменяли и снова хотите проверить корректность программы. Запускать ещё несколько раз? А если потом снова что-то поменяется? Нельзя ли как-то автоматизировать это дело?
Оказывается, можно. В Python встроен модуль unittest, который поддерживает автоматизацию тестов, использование общего кода для настройки и завершения тестов, объединение тестов в группы, а также позволяет отделять тесты от фреймворка для вывода информации.
Модуль subprocess
Модуль subprocess отвечает за выполнение следующих действий: порождение новых процессов, соединение c потоками стандартного ввода, стандартного вывода, стандартного вывода сообщений об ошибках и получение кодов возврата от этих процессов.
Модуль fractions
Модуль fractions предоставляет поддержку рациональных чисел.
Модуль cmath
Модуль cmath – предоставляет функции для работы с комплексными числами.
Модуль glob
Модуль glob находит все пути, совпадающие с заданным шаблоном в соответствии с правилами, используемыми оболочкой Unix. Обрабатываются символы «*» (произвольное количество символов), «?» (один символ), и диапазоны символов с помощью []. Для использования тильды «~» и переменных окружения необходимо использовать os.path.expanduser() и os.path.expandvars().
Модуль copy — поверхностное и глубокое копирование объектов
Операция присваивания не копирует объект, он лишь создаёт ссылку на объект. Для изменяемых коллекций, или для коллекций, содержащих изменяемые элементы, часто необходима такая копия, чтобы её можно было изменить, не изменяя оригинал. Данный модуль предоставляет общие (поверхностная и глубокая) операции копирования.
Модуль functools
Модуль functools — сборник функций высокого уровня: взаимодействующих с другими функциями или возвращающие другие функции.
Модуль os.path
os.path является вложенным модулем в модуль os, и реализует некоторые полезные функции для работы с путями.
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Модули
Модуль в языке Python представляет отдельный файл с кодом, который можно повторно использовать в других программах.
Для создания модуля необходимо создать собственно файл с расширением *.py , который будет представлять модуль. Название файла будет представлять название модуля. Затем в этом файле надо определить одну или несколько функций.
Допустим, основной файл программы называется main.py . И мы хотим подключить к нему внешние модули.
Для этого сначала определим новый модуль: создадим в той же папке, где находится main.py, новый файл, который назовем message.py . По умолчанию интерпретатор Python ищет модули по ряду стандартных путей, один из которых — это папка главного, запускаемого скрипта. Поэтому, чтобы интерпретатор подхватил модуль message.py, для простоты оба файла поместим в один проект.
Соответственно модуль будет называться 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 не будет работать.
Данный подход с проверкой имени модуля является более рекомендуемым подходом, чем просто вызов метода main.
В файле main.py также можно сделать проверку на то, является ли модуль главным (хотя в прицнипе это необязательно):
import message def main(): message.print_message("Hello work") # Message: Hello work if __name__ == "__main__": main()
Python предоставляет ряд встроенных модулей, которые мы можем использовать в своих программах. В следующих статьях рассмотрим основные из них.
Python модули и пакеты
При написании объёмного кода, часто прибегают к разбиению такового на логически независимые блоки и к последующему выносу в другие файлы. Это повышает читаемость как самого кода, так и проекта целиком. Что влечет за собой менее ресурсозатратную поддержку(дальнейшую модификацию кодовой базы для разных нужд).
После разделения кода по файлам, следует выстроить их взаимодействие. В языке программирования Python данный механизм реализуется с использованием import. Импортировать можно любые компоненты(если Вы кодом не ограничивали таковые) модулей или пакетов.
Модули также могут быть написаны и на других языках, но данная статья направлена на рассмотрение использования данного механизмах в рамках Python.
Модули
В языке программирования Python модулями являются все файлы с расширением *.py (* обозначает, что на этом месте может стоять любой символ или любое их количество). Исключением является служебный файл __init__.py (о назначении которого описано далее в статье).
Дальше стоит понимать, что любая программа имеет некую точку входа. Это своего рода место с которого стартует наш скрипт. В языках предшественниках данной точкой служила функция main и могла быть лишь только одной. В нашем случае допускается отсутствие таковой, но это снижает качество кода, делая его сложным и малопредсказуемым(при импорте код содержащийся на верхнем уровне исполняется). Для того чтобы указать точку входа(может быть указана только в модулях) используется специальная переменная __name__ , в которой содержится наименование текущего модуля или пакета. Если текущий модуль находится на верхнем уровне исполнения(мы явно его передали на исполнение Python), то он называется __main__ независимо от названия файла.
# Указание входной точки ## Если __name__ равно "__main__" исполни if __name__ == "__main__": print('Я главный!') # Вызов других функций, например main()
Для примера реализуем простой модуль, который будет возвращать нам информацию:
# http_get.modules.http_get # Расположен в дирректории http_get, modules и назван http_get def get_dict(): return # Поскольку зависимых импортов нет, мы можем исполнить этот код для проверки # Т.е. в качестве входной точки использовать нашу функцию # Данный код исполнится только, когда этот файл будет исполняемым(не импортируемым) if __name__ == '__main__': print(get_dict())
Далее в корне создадим main.py файл, в который импортируем наш модуль двумя разными способами(об импортах описано в статье):
# main.py from ModulesAndPackages.module_examples.http_get.modules.http_get import get_dict as absolute from http_get.modules.http_get import get_dict as relative def main(): # Работает print(absolute()) print(relative()) if __name__ == '__main__': main()
Все без проблем исполняется.
Трудности
При переносе файлов куда-либо из директории возникнут проблемы из-за первого импорта( main.py ). Поскольку часто приходится писать один и тот же код, использование уже хорошо написанного пакета или модуля может экономить много времени, но исправление большого количества импортов требует Ваших ресурсов. Хорошо написанный пакет, модуль или импорт может экономить ваши рабочие часы, а иногда и нервы.
Не изменяя наши модули(импорты), при изменении положения файлов возникает ошибка импорта:
# Не работает в другом проекте from ModulesAndPackages.module_examples.http_get.modules.http_get import get_dict as absolute # Всегда работает from http_get.modules.http_get import get_dict as relative def main(): print(absolute()) print(relative()) if __name__ == '__main__': main()
Пакеты
В языке программирования Python пакетами являются все директории(вне зависимости от наличия в них модулей), содержащие файл __init__.py , который исполняется при импорте пакета и несет его название ( __name__ ).
Для примера реализуем простой пакет( package ), на базе вышеописанного модуля( http_get.py ):
# package/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package/__init__.py from .modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()
А также реализуем простой пакет с такой же логикой, но с использованием абсолютного импорта:
# package_2/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package_2/__init__.py from ModulesAndPackages.package_examples.package_2.modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()
В корне директории(на уровень выше пакета) создадим файл, в котором воспользуемся нашими пакетами( main.py ):
# main.py from package import get_data from package_2 import get_data as get_data_2 def main(): # Работает print(get_data()) print(get_data_2()) if __name__ == '__main__': main()
Все работает без ошибок.
Трудности
Но при переносе нашего package_2 в другой проект, он теряет свою работоспособность из-за ошибки импортирования в __init__.py файле, в отличии от package .
# package_transferring/package/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package_transferring/package/__init__.py from .modules.http_get import get_dict . def get_data(): return get_dict() . # Не работает # __init__ не может иметь точки входа # # if __name__ == '__main__': # get_data()
# package_transferring/package_2/modules/http_get.py def get_dict(): return if __name__ == '__main__': print(get_dict())
# package_transferring/package_2/__init__.py # Ошибка импорта т.к. изменилась директория from ModulesAndPackages.package_examples.package_2.modules.http_get import get_dict . def get_data(): return get_dict() . # Does not work! # Because init file in package could not have entry point # # if __name__ == '__main__': # get_data()
# package_transferring/main.py from package import get_data # Ошибка импорта from package_2 import get_data as get_data_2 def main(): print(get_data()) print(get_data_2()) if __name__ == '__main__': main()
P.S.
Данная статья написана для новичков, которые изучают язык программирования Python. Задача которой продемонстрировать на простых примерах способы написания пакетов и модулей(не является туториалом), а так же показать какие трудности могут возникнуть и пути их решения.
Github с проектом к данной статье: ModulesAndPackages
Может быть полезно выгрузить модуль или пакет и попробовать внедрить его в свой проект.