Где найти описание подключаемых модулей в Python?
Как узнать, какие есть функции в подключаемых модулях Python, что они делают и как их используют в коде?
Отслеживать
user262779
задан 6 дек 2018 в 20:14
Магомед Азизов Магомед Азизов
31 1 1 серебряный знак 3 3 бронзовых знака
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Это можно сделать с помощью встроенной функции help , например, из интерактивной консоли. Для этого передайте ей как параметр имя модуля, о котором хотите узнать, в виде строки. Так вы можете получить описание стандартного или установленного модуля. Например:
>>> help('math') Help on built-in module math: NAME math DESCRIPTION This module is always available. It provides access to the mathematical functions defined by the C standard. FUNCTIONS acos(. ) acos(x) Return the arc cosine (measured in radians) of x. acosh(. ) acosh(x) Return the inverse hyperbolic cosine of x. asin(. ) asin(x) Return the arc sine (measured in radians) of x. asinh(. ) asinh(x) Return the inverse hyperbolic sine of x. atan(. ) atan(x) Return the arc tangent (measured in radians) of x. atan2(. ) atan2(y, x) Return the arc tangent (measured in radians) of y/x. Unlike atan(y/x), the signs of both x and y are considered. atanh(. ) atanh(x) Return the inverse hyperbolic tangent of x. ceil(. ) ceil(x) Return the ceiling of x as an Integral. This is the smallest integer >= x. copysign(. ) copysign(x, y) Return a float with the magnitude (absolute value) of x but the sign of y. On platforms that support signed zeros, copysign(1.0, -0.0) returns -1.0. cos(. ) cos(x) Return the cosine of x (measured in radians). cosh(. ) cosh(x) Return the hyperbolic cosine of x. degrees(. ) degrees(x) Convert angle x from radians to degrees. erf(. ) erf(x) Error function at x. erfc(. ) erfc(x) Complementary error function at x. exp(. ) exp(x) Return e raised to the power of x. expm1(. ) expm1(x) Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. fabs(. ) fabs(x) Return the absolute value of the float x. factorial(. ) factorial(x) -> Integral Find x!. Raise a ValueError if x is negative or non-integral. floor(. ) floor(x) Return the floor of x as an Integral. This is the largest integer int greatest common divisor of x and y hypot(. ) hypot(x, y) Return the Euclidean distance, sqrt(x*x + y*y). isclose(. ) isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool Determine whether two floating point numbers are close in value. rel_tol maximum difference for being considered "close", relative to the magnitude of the input values abs_tol maximum difference for being considered "close", regardless of the magnitude of the input values Return True if a is close in value to b, and False otherwise. For the values to be considered close, the difference between them must be smaller than at least one of the tolerances. -inf, inf and NaN behave similarly to the IEEE 754 Standard. That is, NaN is not close to anything, even itself. inf and -inf are only close to themselves. isfinite(. ) isfinite(x) -> bool Return True if x is neither an infinity nor a NaN, and False otherwise. isinf(. ) isinf(x) -> bool Return True if x is a positive or negative infinity, and False otherwise. isnan(. ) isnan(x) -> bool Return True if x is a NaN (not a number), and False otherwise. ldexp(. ) ldexp(x, i) Return x * (2**i). lgamma(. ) lgamma(x) Natural logarithm of absolute value of Gamma function at x. log(. ) log(x[, base]) Return the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x. log10(. ) log10(x) Return the base 10 logarithm of x. log1p(. ) log1p(x) Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. log2(. ) log2(x) Return the base 2 logarithm of x. modf(. ) modf(x) Return the fractional and integer parts of x. Both results carry the sign of x and are floats. pow(. ) pow(x, y) Return x**y (x to the power of y). radians(. ) radians(x) Convert angle x from degrees to radians. sin(. ) sin(x) Return the sine of x (measured in radians). sinh(. ) sinh(x) Return the hyperbolic sine of x. sqrt(. ) sqrt(x) Return the square root of x. tan(. ) tan(x) Return the tangent of x (measured in radians). tanh(. ) tanh(x) Return the hyperbolic tangent of x. trunc(. ) trunc(x:Real) -> Integral Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method. DATA e = 2.718281828459045 inf = inf nan = nan pi = 3.141592653589793 FILE (built-in)
Также можно поискать документацию интересующего модуля в Интернете. Документацию стандартных модулей можно найти в официальной документации языка python, здесь. Информацию о сторонних модулях можно найти на PyPI. Например, вот документация модуля numpy.
Ликбез по пакетам и шпаргалка по модулям в Python

Как вы, возможно знаете, код на Python хранится в модулях (modules), которые могут быть объединены в пакеты (packages). Это руководство призвано подробно рассказать именно о пакетах, однако совсем не упомянуть модули нельзя, поэтому я немного расскажу и о них. Многое из того, что применимо к модулям, справедливо и для пакетов, особенно если принять во внимание тот факт, что каждый, как правило, ведёт себя как модуль.
Кратко о модулях
Модуль в Python — это файл с кодом. Во время же исполнения модуль представлен соответствующим объектом, атрибутами которого являются:
- Объявления, присутствующие в файле.
- Объекты, импортированные в этот модуль откуда-либо.
При этом определения и импортированные сущности ничем друг от друга не отличаются: и то, и другое — это всего лишь именованные ссылки на некоторые объекты первого класса (такие, которые могут быть переданы из одного участка кода в другой как обычные значения).
Такое единообразие удобно, например, при рефакторинге: мы можем разделить один разросшийся модуль на несколько, а потом импортировать вынесенные определения в оригинальный модуль. При этом с точки зрения внешнего наблюдателя переработанный модуль будет иметь те же атрибуты, которые имел до внесения изменений, а значит у пользователей модуля ничего в коде не сломается.
Модули и видимость содержимого
В Python нет настоящего сокрытия атрибутов объектов, поэтому и атрибуты объекта модуля так или иначе всегда доступны после импорта последнего. Однако существует ряд соглашений, которые влияют на процесс импортирования и поведение инструментов, работающих с кодом.
Так атрибуты, имя которых начинается с одиночного подчёркивания, считаются как бы помеченными «для внутреннего использования», и обычно не отображаются в IDE при обращению к объекту «через точку». И linter обычно предупреждает об использовании таких атрибутов, мол, «небезопасно!». «Опасность» состоит в том, что автор кода имеет полное право изменять состав таких атрибутов без уведомления пользователей кода. Поэтому программист, использовавший в своём коде приватные части чужого кода рискует в какой-то момент получить код, который перестанет работать при обновлении сторонней библиотеки.
Итак, мы можем определять публичные атрибуты модуля, приватные атрибуты (так называют упомянутые выше атрибуты «для внутреннего пользования»). И данное разделение касается не только определений, содержащихся в самом модуле, но и импортируемых сущностей. Ведь все импортированные объекты становятся атрибутами и того модуля, в который они импортированы.
Есть и третья группа атрибутов — атрибуты, добавляемые в область видимости при импортировании всего содержимого модуля («со звёздочкой», from module import * ). Если ничего явно не указывать, то при таком импортировании в текущую область видимости добавятся все публичные атрибуты модуля. Помимо данного умолчания существует и возможность явно указать, что конкретно будет экспортировано при импорте со звёздочкой. Для управления названным методом импорта существует атрибут __all__ , в который можно положить список (а ещё лучше — кортеж) строк с именами, которые будут экспортироваться.
Живой пример видимости атрибутов модулей.
Рассмотрим пример, демонстрирующий всё вышеописанное. Пусть у нас будет два файла:
# Файл "module.py" from other_module import CAT, DOG as _DOG, _GOAT FISH = 'fish' MEAT = 'meat' _CARROT = 'carrot' __all__ = ('FISH', '_CARROT')
# Файл "other_module.py" CAT = 'cat' DOG = 'dog' _GOAT = 'goat'
Рассмотрим сначала обычный импорт import module . Если импортировать модуль таким образом, то IDE, REPL и остальные инструменты «увидят» у модуля следующие атрибуты:
- FISH , MEAT т.к. имена констант — публичные,
- CAT , т.к. константа импортирована под публичным именем.
А эти атрибуты не будут видны:
- _DOG , т.к. при импортировании константа переименована в приватной манере,
- _GOAT , т.к. импортирована по своему приватному имени (тут линтер может и поругать за обращение к приватному атрибуту модуля!),
- _CARROT , ибо приватная константа.
Импорт import other_module я не рассматриваю как тривиальный случай.
Теперь рассмотрим импорт всего содержимого module:
from module import *
После импортирования в текущей области видимости мы получим ровно два новых имени: FISH и _CARROT — именно они перечислены в атрибуте __all__ . Заметьте, что в данном случае при массовом импорте добавится даже приватный атрибут, потому что он явно указан!
Последствия импорта from other_module import * тоже очевидны и я их не рассматриваю.
Наконец-то, пакеты!
Пакет в Python — директория с обязательным модулем __init__.py . Остальное содержимое опционально и может включать в себя и модули, и другие пакеты.
Импортирование пакетов
Пакет с единственным модулем __init__.py при импорте ведёт себя как обычный модуль. Содержимое инициализирующего модуля определяет атрибуты объекта пакета.
Прочие модули пакета и вложенные пакеты не импортируются автоматически вместе с пакетом-родителем, но могут быть импортированы отдельно с указанием полного имени. Важный момент: при импортировании вложенного модуля всегда сначала импортируются модули инициализации всех родительских пакетов (если оные ещё ни разу не импортировались, но об этом я расскажу ниже).
Рассмотрим, к примеру, следующую структуру директорий и файлов:
Когда мы импортируем модуль submodule.py , то фактически происходит следующее (именно в таком порядке):
- загружается и выполняется модуль package/__init__.py ,
- загружается и выполняется package/subpackage/__init__.py ,
- наконец, импортируется package/subpackage/submodule.py .
При импорте package.module предварительно загружается только package/__init__.py .
Так что же, если мы загрузим парочку вложенных модулей, то для каждого будет выполняться загрузка всех __init__.py по дороге? Не будет! Подсистема интерпретатора, отвечающая за загрузку модулей, кэширует уже загруженные пакеты и модули. Каждый конкретный модуль загружается ровно один раз, в том числе и инициализирующие модули __init__.py (короткие имена модулей хоть и одинаковы, но полные имена всегда разные). Все последующие импортирования модуля не приводят к его загрузке, только лишь нужные атрибуты копируются в соответствующие области видимости.
Пакеты и __all__
В целом атрибут __all__ в модуле инициализации пакета ведёт себя так же, как и в случае с обычным модулем. Но если при импорте пакета «со звёздочкой» среди перечисленных имён встретится имя вложенного модуля, а сам модуль не окажется импортирован ранее в этом же __init__.py , то этот модуль импортируется неявно! Очередной пример это продемонстрирует.
Вот структура пакета:
Файл же package/__init__.py содержит следующее (и только это!):
__all__ = ('a', 'b')
А импортируем мы from package import * . В области видимости у нас окажутся объекты модулей a и b под своими именами (без полного пути, то есть без package. ). При этом сами модули в коде нигде явно не импортируются! Такая вот «автомагия».
Указанный автоматизм достаточно ограничен: не работает «вглубь», например — не импортирует «через звёздочку» указанные модули и подпакеты. Если же вам вдруг такого захочется, вы всегда сможете на соответствующих уровнях в __init__.py сделать from x import * и получить в корневом пакете плоскую область видимости со всем нужным содержимым. Но такое нужно довольно редко, потому что «не помогает» ни IDE, ни ручному поиску по коду. Впрочем, знать о фиче и иметь её в виду — не вредно, как мне кажется.
Изучайте Python на Хекслете Первые курсы в профессии Python-программист доступны бесплатно сразу после регистрации. Начните сегодня, учитесь в комфортном для вас темпе.
Пакеты, модули и точки входа
С модулем __init__.py разобрались. Настала очередь модуля __main__.py . Этот модуль позволяет сделать пакет исполняемым посредством вызова python -m … . Те из вас, кому знакомо оформление точки входа в модулях, могут догадаться, откуда ноги растут у магического выражения __name__ == ‘__main__’ — да, отсюда! Для остальных напоминаю: чтобы модуль сделать «исполняемым, но не при импорте», в конец модуля дописывается конструкция
if __name__ == '__main__': main() # тут что-то выполняем
У модуля, который скармливается интерпретатору напрямую ( python file.py ) или в роли претендента на запуск ( python -m module ), атрибут __name__ будет содержать то самое магическое ‘__main__’ . А в остальное время атрибут содержит полное имя модуля. С помощью условия, показанного выше, модуль может решить, что делать при запуске.
У пакетов роль атрибута выполняет специальный файл __main__.py . Когда мы запустим пакет через python path/to/package или python -m package , интерпретатор будет искать и выполнять именно этот файл.
Более того, модули __main__ нельзя импортировать обычным способом, поэтому можно не бояться случайного импорта и писать команды прямо на верхнем уровне: всё равно странно в модуле с именем __main__ проверять, что его имя равно __main__ (хе-хе!).
А ещё модуль __main__.py удобен тем, что его можно класть в корень вашего проекта, после чего запускать проект можно будет с помощью команды python . ! Лаконично, не правда ли?
PEP 420, или неявные пространства имён
Раз уж развёл ликбез, расскажу и про эту штуку.
Долгое время в Python пакеты были обязаны иметь файл __init__.py — наличие этого файла позволяло отличить пакет от обычной директории с модулями (с которыми Python работать не мог). Но с версии Python3.3 вступил в силу PEP 420 , позволяющий создавать пространства имён «на вырост».
Теперь вы можете создавать пакет без __init__.py , и такой пакет сможет существовать полноценно, разве что при импорте содержимого не будет производиться инициализация. Но, конечно же, данное изменение делалось не с целью сэкономить на файлах. Подобные пакеты могут встречаться в путях поиска пакетов (о поиске пакетов я ниже расскажу) более одного раза: все встреченные структуры с общим корневым именем при загрузке схлопнутся в одно пространство имён.
Тут стоит отметить, что с полноценными пакетами подобное не срабатывало ранее и не будет работать в будущем. Если среди путей пакет с модулем инициализации находится в первый раз, все последующие пакеты с тем же именем будут проигнорированы. Это защищает вас от смешивания сторонних пакетов с системными. И даже просто от ошибок именования: назвав пакет так же, как называется встроенный пакет или модуль, вы получите ошибку — ваши определения не будут импортироваться.
Пакеты — пространства имён (Namespace Packages, NP) — а именно так называются пакеты без инициализации — не могут объединяться с полноценными пакетами, поэтому добавить что-то в системный пакет вам также не удастся. И тут всё защищено!
Какая же польза от неявных пространств имён? А вы представьте себя авторами, скажем, игрового движка. Вы хотите весь код держать в общем пространстве имён engine , но при этом не желаете, чтобы весь код поставлялся одним дистрибутивом (не каждому же пользователю нужны все-все компоненты движка). С NP вы можете в нескольких дистрибутивах использовать общее корневое имя engine , но разные подпакеты и подмодули. А на выходе вы получите возможность делать импорты вида
from engine import graphics, sound
Важно: помните, если встретятся обычный пакет и NP с одинаковым именем, то победит обычный пакет! А NP, сколько бы их не было, не будут загружены!
Циклические импорты
Если вдруг вы захотите в один модуль импортировать другой, а другой захочет, пусть даже и не напрямую, импортировать первый, то вы получите ImportError . Потому что у вас случится циклический импорт. Про оный нужно просто знать и стараться архитектурить код так, чтобы циклов не случалось.
Если же приспичивает, и импортировать что-то «ну очень нужно», то можно попробовать обойтись локальным импортом:
### foo.py import bar A = bar(42)
### bar.py # import foo — тут не импортируем def bar(x): return x + 1 def baz(): import foo # а тут уже можно return foo.A
Да, это костыль. Но иногда полезный. В идеале — до ближайшего большого рефакторинга. Поэтому настраивайте linter на ловлю локальных импортов и стремитесь убирать такие костыли хоть когда-нибудь!
Поиск пакетов и модулей
Пайтон ищет модули и пакеты в директориях, во время исполнения перечисленных в списке sys.path — по порядку от первого пути к последнему.
В этом списке пути до стандартных библиотек обычно расположены раньше, чем директории со сторонними пакетами, чтобы нельзя было случайно заменить стандартный пакет сторонним (помним: кто первый, того и тапки — среди нескольких с одинаковыми именами загружается первый попавшийся пакет).
В списке путей (обычно в начале) присутствует и путь » , означающий текущую директорию. Это, в свою очередь, означает, что модули и пакет в текущем проекте имеют больший приоритет.
Обычно пути трогать не нужно, всё вполне нормально «работает само». Но если очень хочется, то путей у вас несколько:
- Использовать переменную окружения PYTHONPATH (значение — строка с путями, разделёнными символом : ),
- Во время исполнения изменить sys.path .
Первый способ — простой и понятный. Не сложнее добавления пути до исполняемых файлов в PATH (даже синтаксис тот же).
Второй способ — сложный и требующий внимательности. Дело в том, что sys.path нужно изменять максимально рано — где-нибудь в точке входа. Если не торопиться менять sys.path , то что-то уже может успеть загрузиться до того, как вы перестроите пути для поиска пакетов. А ведь эта загрузка может произойти в другом потоке исполнения! Отлаживать проблемы с очерёдностью загрузки модулей сложно. Лучше просто их не создавать.
Кстати, когда вы используете виртуальные окружения, sys.path будет содержать пути до локальных копий стандартных библиотек. Именно это позволяет виртуальному окружению быть самодостаточным (работать на любой машине с подходящей ОС — даже без установленного в систему Python!).
Что не было раскрыто?
Я специально не стал рассказывать про
- создание модулей и пакетов на лету (без использования файлов исходников);
- загрузку модулей не с диска, а из других источников;
- расширение подсистемы импортирования с целью загрузки в виде объектов-модулей чего-то, не являющегося кодом вовсе (XML, CSV, JSON).
Темы эти насколько интересны, настолько и велики. На наше счастье, самим разбираться в такой тонкой и сложной машинерии приходится редко. Мы просто пользуемся готовыми магическими артефактами, а зачаровывают их другие 🙂 Если же вы захотите научиться магии, документация вам в руки.
Как посмотреть содержимое библиотеки python

Python обладает великолепной документацией и предоставляет удобные способы для работы с ней: от официального сайта до встроенной справочной системы.
Работа с документацией является одной из важных составляющих деятельности разработчика. И это не только чтение документации к библиотекам и комментариев в коде, но и документирование собственного кода, а также поддержание его в актуальном состоянии. Качественно задокументированный код во многих случаях упрощает его поддержание и сокращает время на «вхождение» новых сотрудников в проект. Если же речь идет об изучении нового языка программирования, качество документации и поддержка сообщества могут сыграть решающую роль в освоении материала и снизить порог вхождения.
Документация к языку программирования Python обладает всеми качествами, которые отличают «хорошую» документацию от «плохой». Тем не менее, новички часто сталкиваются с рядом вопросов. Как быстро найти информацию о классе или функции? Как самому писать документацию к коду? Какие инструменты можно использовать при документировании кода? На эти вопросы мы и постараемся ответить в статье.
Основной источник информации о Python
Безусловно, основным, наиболее полным и актуальным источником информации о Python является сайт c официальной документацией. Главная страница сайта предоставляет удобную навигацию по разделам.
Важные разделы сайта (полезно начинающим программистам):
- Setup and Usage — содержит информацию об установке и настройке Python на разных платформах;
- Tutorial — учебное пособие для новичков, с которого и рекомендуется начинать свой путь в мир Python;
- Library Reference — подробное описание стандартной библиотеки Python;
- Python HOWTO — различные руководства по конкретным темам;
- Language Reference — раздел для тех кто, хочет знать подробности реализации СPython.
Поиск по сайту с документацией
Для поиска по сайту имеются: окно быстрого поиска по ключевым словам и таблицы с индексами для поиска по названию модуля (класса, метода, переменной). Важно: Python динамично развивается, постоянно добавляются новые возможности и функционал. Если вы хотите работать с актуальной документацией — выберите необходимую вам версию Python в выпадающем меню в шапке сайта.
Создатели Python предусмотрели возможность установить документацию локально на компьютере. Для этого необходимо перейти на страницу загрузки, выбрать версию Python, формат файлов (доступны pdf, epub, html, txt) и способ архивирования. После скачивания и распаковки архива, вы можете пользоваться документацией в полном объеме.
Встроенная справочная система
Чтение объемного справочного руководства полезно на этапе изучения языка. При работе с кодом чаще возникает необходимость получить небольшую справку о работе той или иной функции, получаемых аргументах, или о наличии у класса атрибутов и методов. В таких случаях информация из официальной документации, как правило, избыточна, а поиск по ней может может занять значительное время. В Python для таких случаев существует встроенная справочная система, позволяющая быстро получить краткую справку об объекте.
Небольшое уточнение: поскольку в Python все является объектом, в том числе методы и классы, далее мы будем часто употреблять термин «объект» применительно к целям получения информации.
Доступ к встроенной справочной системе осуществляется с помощью функции help . Для получения справки по тому или иному объекту необходимо в интерпретаторе Python вызвать функцию help , а в качестве аргумента передать сам объект или строку с названием объекта.

В приведенном выше примере, мы вызвали справку по функции ord . В тексте сообщения содержится информация о том, что делает функция и к какому модулю она относится.
Теперь попробуем получить информацию о модуле стандартной библиотеки os .

Почему вызов функции завершился выбросом исключения? Ведь модуль os входит в стандартную библиотеку и маловероятно, что справочная информация по нему не была включена.
Docstring
Чтобы ответить на этот вопрос, давайте разберемся, где хранится справочная информация и как работает функция help . Как уже говорилось выше, все в Python является объектом. Все объекты в Python имеют специальный атрибут __doc__ , предназначенный для хранения строки документации — docstring. Вот как определено понятие docstring в официальной документации: «Docstring — строковый литерал, который встречается как первый оператор в определении модуля, функции, класса или метода. Такой docstring становится специальным атрибутом __doc__ этого объекта».
Посмотрим, что хранится в атрибуте __doc__ объекта ord.

Размещение справки об объекте в исходном коде самого объекта позволяет элегантно решить вопрос хранения информации и доступа к ней. Функция help при передаче ей в качестве аргумента объекта для получения информации о нем, обращается к атрибуту __doc__ этого объекта. Поскольку модуль os не импортирован, он отсутствует в глобальной области видимости и не доступен при вызове функции help . Именно по этой причине мы получаем ошибку. Для решения проблемы достаточно импортировать модуль. Есть еще один способ избежать ошибки и не связанный с импортом объекта — передать в качестве аргумента в функцию help строку с именем объекта.

В этом случае функция help для получения информации будет использовать модуль стандартной библиотеки pydoc , который выполнит импорт объекта и генерацию справки.
Посмотрим на исходный код модуля os и убедимся в том, что docstring и содержимое атрибута os . __doc__ совпадают. Из приведенного кода видно, как определяются в коде docstring. Строки документации заключаются в тройные кавычки и пишутся сразу под заголовком объекта.
Вы уже заметили, что вывод функции help отличается от вывода, полученного через обращение к атрибуту __doc__ объекта. Он более информативен и выводит информацию в виде форматированного текста. У функции help есть еще одна особенность, повышающая удобство работы со справочной системой. При вызове help без аргументов запускается интерактивный режим справочной системы. Для получения справки в нем достаточно набрать только название интересующего нас объекта. Запустив интерактивный режим в отдельном терминале, мы получаем удобный инструмент для работы с документацией.
Встроенная справочная система
Стандартная библиотека Python весьма обширна и содержит большое количество модулей. Помнить их все, в том числе и заложенный функционал, невозможно. Что делать, если мы не помним (не знаем) название модуля, класса или функции? Ниже приведены несколько примеров, помогающих в таких ситуациях.
Получение списка доступных модулей:

Получение ключевых слов:

Получение списка названий встроенных функций:

Весьма полезной и часто используемой разработчиками функцией является dir . В качестве аргумента она принимает объект и возвращает список допустимых атрибутов для этого объекта. Это один из способов узнать, какие методы и атрибуты содержит объект.

Как задокументировать собственный код?
Теперь, когда мы знаем о docstring и работе функции help , мы можем задокументировать свой код. В качестве примера возьмем скрипт factorial. py:

Добавим docstring.

Убедимся в наличии документации по модулю factorial :

Вызов help (factorial) вернет справку:

При создании документации к коду стоит придерживаться правил и рекомендаций, описанных в PEP257 и PEP8. Ссылки на эти документы приведены в конце статьи.
О библиотеке pydoc
Мы уже упоминали модуль стандартной библиотеки pydoc . Он автоматически генерирует документацию из модулей Python. Документация может быть представлена в виде страниц текста на консоли, отображаться в браузере или сохраняться в HTML-файлах.
Команда pydoc позволяет вывести текст справки прямо в терминале (не интерпретаторе Python):

Для создания документации в виде HTML-страниц используется ключ -w . Это позволяет организовать хранение документации отдельно от кода.

Для поиска по docstring модулей используется ключ -k . В качестве аргумента в этом случае передается ключевое слово. В результате будут выведены названия всех модулей в docstring которых встречается ключевое слово.

Обратим ваше внимание на одну особенность поиска по документации при использовании ключа -k . Поиск производится только по первым строкам документации модулей. Тем не менее, данный функционал может быть весьма полезным в некоторых случаях.
Для любителей работать в браузере, предусмотрена возможность запуска HTTP-сервера документации, который будет доступен по порту, указанному после ключа -p .

В третьей версии Python для управления сервером добавлена пара команд: b — открытие страницы документации в браузере, q — завершения работы сервера. При вызове команды pydoc3 с ключом -b произойдет запуск сервера и автоматическое открытие страницы в браузере. В документацию также будут включены модули, расположенные в директории из которой был запущен сервер.
Соблюдение соглашений
При документировании кода важно соблюдать принятые в языке программирования соглашения. Для решения этих задач существуют различные инструменты. В этой статье мы становимся на одном из них — модуле pydocstyle .
Модуль pydocstyle — это инструмент статического анализа для проверки соответствия docstring соглашениям, принятым в Python. Установка модуля осуществляется с помощью менеджера пакетов pip:
Язык Python
Стандартная библиотека python очень обширна. В ней есть инструменты для работы с файловой системой, сервисами операционной системы, поддержка многопоточности, инструменты для работы с сетью и многие другое. В этом разделе мы рассмотрим несколько стандартных модулей python.
Работа с операционной системой
Модуль sys
Модуль sys обеспечивает доступ к параметрам и функциям операционной системы.
Список sys.argv хранит имя запущенного скрипта и аргументы командной строки, переданные при его запуске:
# test.py import sys for idx, item in enumerate(sys.argv): print(f'Arg idx>: item:8> type(item)>')
user@host:~$ python test.py arg1 arg2 345 Arg 0: test.py 'str'> Arg 1: arg1 'str'> Arg 2: arg2 'str'> Arg 3: 345 'str'>
Переменная sys.executable позволяет узнать какой именно интерпретатор python используется:
print(sys.executable) # /home/vitaly/miniconda3/envs/tf2/bin/python
Функция sys.exit позволяет завершить выполнение программы. Эта функция принимает один аргумент — код выхода, который по умолчанию равен нулю. Большинство систем будет считать код 0 признаком успешного завершения программы, а любое другое число от 1 до 127 будет считать признаком ненормального завершения. Если передан объект другого типа, то он будет выведен в стандартный поток вывода, а код выхода будет равен 1. Функция sys.exit всегда генерирует исключение SystemExit, поэтому не стоит рассматривать ее как стандартный способ завершения программы. Используйте ее только в подходящих случаях, которые чаще всего связаны с невозможностью продолжения работы программы.
Переменная sys.path обеспечивает доступ к переменной окружения PYTHONPATH . Эта переменная содержит список путей, в которых выполняется поиск модулей. Если необходимый модуль расположен в директории, которая не входит в PYTHONPATH , то перед подключением этого модуля необходимо добавить эту директорию в переменную sys.path :
# 'path/to/my/facorite/module/dir/mymodule.py' sys.path.append('path/to/my/facorite/module/dir') import mymodule
Можно указывать абсолютный или относительный путь. Модуль sys имеет еще много инструментов, которые описаны в документации.
Модуль os
Модуль os предоставляет инструменты для работы с операционной системой и файловой системой.
Функции os.getenv и os.putenv позволяют получать и изменять значения переменных окружения. Функция os.system позволяет выполнять консольные команды, запуская при этом дочерний процесс. Рассмотрим следующий скрипт:
# test.py import os import sys print(f' HOME: os.getenv("HOME")>') os.putenv('NEWENV', 'value') print(f'NEWENV: os.getenv("NEWENV")>') if os.getenv('NEWENV') is not None: sys.exit(0) os.system('python test.py')
При работе скрипта можно получить вывод, подобный такому:
HOME: /home/vitaly NEWENV: None HOME: /home/vitaly NEWENV: value
Разберемся с тем что произошло. Переменная окружения HOME содержит путь к домашней директории пользователя. Мы получили значение этой переменной с помощью os.genenv (в данном случае /home/vitaly ) и вывели его в консоль. Затем, c помощью sys.putenv , мы задали значение value новой переменной окружения NEWENV и сразу прочитали его. Функция os.getenv вернула None , поскольку функция sys.putenv оказывает влияние только на окружение дочерних процессов. Чтобы это проверить, мы снова запустили интерпретатор python с нашим скриптом test.py , используя os.system . В дочернем процессе снова были выведены переменные окружения HOME и NEWENV . В дочернем процессе переменная NEWENV определена, поэтому сработало условие для выхода из программы с помощью sys.exit(0) .
Функция os.listdir возвращает список названий объектов, лежащий в заданной директории.
Модуль os.path
Модуль os.path содержит полезные инструменты для работы с путями файловой системы. Функция os.path.exists проверяет указывает ли путь на существующий объект в файловой системе. Функция os.path.isfile имеет схожий смысл, но возвращает True только в том случае, если объект является обычным файлом (не директория и не ссылка):
os.path.exists('/home/vitaly') # True os.path.exists('/home/david') # False os.path.isfile('/home/vitaly') # False
Функции os.path.join , os.path.split и os.path.splitext выполняют часто встречающиеся манипуляции со строками путей:
path = os.path.join('/home', 'vitaly', 'test.py') # /home/vitaly/test.py head, tail = os.path.split(path) # ['/home/vitaly', 'test.py'] root, ext = os.path.splitext(path) # ['/home/vitaly/test', '.py']
Модуль shutil
Модуль shutil предоставляет высокоуровневые инструменты для операций с файлами. Вот несколько примеров:
# копирование файла в директорию shutil.copy('filename', 'path/to/dir') # копирование файла в файл с другим именем shutil.copyfile('filename1', 'filename2') # рекурсивное копирование директории dir1 в директорию dir2 shutil.copytree('path/to/dir1', 'path/to/dir2') # рекурсивное удаление содержимого директории dir shutil.rmtree('path/to/dir') # рекурсивное перемещение файла или директории shutil.move(src, dst)
Модуль glob
Модуль glob позволяет выполнять поиск объектов в файловой системе, имена которых удовлетворяют заданному паттерну:
# список текстовых файлов в текущей директории text_files = glob.glob('./*.txt') # рекурсивный поиск файлов с расширением .py, # начиная с текущей директории text_files_all = glob.glob('./**/*.py', recursive=True)
Работа со строками
Модуль string
Модуль string содержит различные инструменты для работы со строками, многие из которых дублируют возможности стандартного типа str . Модуль string содержит набор констант, которые часто оказываются полезны:
string.ascii_lowercase # 'abcdefghijklmnopqrstuvwxyz' string.ascii_uppercase # 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' string.ascii_letters # 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' string.digits # '0123456789' string.punctuation # !"#$%&'()*+,-./:;?@[\]^_`<|>~
Модуль re
Модуль re содержит инструменты для работы с регулярными выражениями. Обсуждение регулярных выражений выходит за рамки этого курса. Мы рекомендуем читателю самостоятельно изучить базовые приемы работы с регулярными выражениями.
Вычисления с произвольной точностью
Модуль decimal
Модуль decimal позволяет выполнять арифметические операции с плавающей точной с фиксированной точностью:
from decimal import * getcontext().prec = 6 Decimal(1) / Decimal(7) # Decimal('0.142857') getcontext().prec = 28 Decimal(1) / Decimal(7) # Decimal('0.1428571428571428571428571429')
Объекты Decimal представлены в памяти точно. Это значит, что числа Decimal можно сравнивать с помощью операторов == и != , не опасаясь погрешности из-за округления двоичного представления (как это происходит в случае с типом float ).
В модуле decimal доступны некоторые математические функции:
getcontext().prec = 28 Decimal(2).sqrt() # Decimal('1.414213562373095048801688724') Decimal(1).exp() # Decimal('2.718281828459045235360287471') Decimal('10').ln() # Decimal('2.302585092994045684017991455') Decimal('10').log10() # Decimal('1')
Модуль fractions
Тип Fraction из модуля fractions описывает рациональные числа — числа, которые можно представить в виде обыкновенной дроби:
from fractions import Fraction from math import pi, cos Fraction(16, -10) # Fraction(-8, 5) Fraction('3.1415926535897932').limit_denominator(1000) # Fraction(355, 113) Fraction(cos(pi/3)) # Fraction(4503599627370497, 9007199254740992)
В последнем примере мы воспользовались модулем math , который мы не будем обсуждать, поскольку его возможности перекрываются модулем numpy . Модуль numpy будет рассмотрен в следующих частях.
Продвинутые структуры данных и эффективное итерирование
Модуль queue
Модуль queue содержит реализацию нескольких структур данных, среди которых FIFO-очередь queue.Queue и очередь с приоритетом queue.PriorityQueue . Очередь с приоритетом возвращает не первый добавленный элемент, а наименьший:
from queue import Queue, PriorityQueue arr = [3, 6, 1, 9, 4, 7, 2, 5, 8, 1] q = Queue() for i in arr: q.put_nowait(i) while not q.empty(): print(q.get_nowait(), end=' ') # 3 6 1 9 4 7 2 5 8 1 pq = PriorityQueue() for i in arr: pq.put_nowait(i) while not pq.empty(): print(pq.get_nowait(), end=' ') # 1 1 2 3 4 5 6 7 8 9
Типы модуля queue созданы для работы в многопоточной среде исполнения. С особенностями многопоточной работы, которые мы не будем обсуждать, связано использование методов get_nowait и put_nowait вместо get и put .
Модуль collections
Модуль collections расширяет набор стандартных контейнеров python. Рассмотрим три типа данных из этого модуля.
Функция namedtuple() позволяет создавать типы данных с именованными полями:
from collections import namedtuple Vector = namedtuple('Vector', ['x', 'y', 'z']) v1 = Vector(1., 0.5, 0.6) v1.x # 1. v1.y # 0.5 v1.z # 0.6
Тип deque реализует контейнер двусторонняя очередь, или дек. Это последовательный контейнер, который позволяет эффективно добавлять и удалять элементы в начало и в конец:
from collections import deque deq = deque([1, 3, 5]) deq.append('a') # [1, 3, 5, 'a'] deq.appendleft(False) # [False, 1, 3, 5, 'a'] a = deq.pop() # a = 'a', deq = ['False', 1, 3, 5] b = deq.popleft() # b = False, deq = [1, 3, 5]
Тип Counter является подклассом типа dict и позволяет удобно подсчитывать количество вхождений элементов в контейнере, например:
from collections import Counter the_longest_word_in_english\ = 'pneumonoultramicroscopicsilicovolcanoconiosis' cnt = Counter(the_longest_word_in_english) for key, val in cnt.items(): print(f'key>: val>', end=', ') # p: 2, n: 4, e: 1, u: 2, m: 2, o: 9, l: 3, t: 1, r: 2, a: 2, i: 6, c: 6, s: 4, v: 1 cnt.most_common(1) # [('o', 9)]
Модуль itertools
Модуль itertools содержит множество инструментов для эффективного итерирования по элементам контейнеров. Эффективное в данном случае означает, что необходимое следующее значение генерируется на лету, без хранения всех значений, количество которых может быть очень большое. Рассмотрим несколько инструментов из этого модуля:
import itertools arr = list(range(5)) # arr = [0, 1, 2, 3, 4] for item in itertools.accumulate(arr): print(item, end=' ') # 0 1 3 6 10 for perm in itertools.permutations(arr): print(''.join(map(str, perm)), end=' ') # 01234 01243 01324 01342 01423 01432 . for comb in itertools.combinations(arr, 3): print(''.join(map(str, comb)), end=' ') # 012 013 014 023 024 034 123 124 134 234
Время и дата с модулем datetime
Модуль datetime позволяет полноценно работать с объектами даты и времени:
from datetime import date, timedelta d1 = date.fromisoformat('2019-12-04') d2 = date(2002, 12, 31) d1 d2 # False delta = d1 - d2 delta.days # 6182 type(delta) # delta2 = timedelta(days=15) d3 = d1 + delta2 # 2019-12-19 d3.weekday() # 3 (Среда) d4 = date.today() # 2020-07-15
import time from datetime import datetime dt1 = datetime.fromtimestamp(time.time()) # 2020-07-15 21:47:09.036145 dt2 = datetime.fromisoformat('2020-07-15 21:47:09.036145') dt2.timestamp() # 1594824429.036145 (секунд прошло с 1970-01-01)
Резюме
В этом разделе мы выполнили краткий обзор возможностей некоторых стандартных модулей языка python. На этаме планирования нового проекта на python разумно изучить возможности существующих модулей (не только стандартных). Большое сообщество разработчиков и разнообразие доступных модулей являются сильными сторонами python.
Источники
- docs.python.org/3/library/
- PEP 206. Batteries Included Philosophy
- Введение
- Настройка рабочей среды
- Язык C++
- Язык Python
- Основы синтаксиса языка python
- Строки
- Стандартные модули python, часть I
- ООП в python
- Стандартные модули II
- Итераторы и генераторы
- Вычисления с библиотекой numpy
- Визуализация данных с matplotlib