Книга: Как устроен Python. Гид для разработчиков, программистов и интересующихся
Назад: 23. Исключения
Дальше: 25. Библиотеки: пакеты и модули

24. Импортирование библиотек

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

Чтобы использовать библиотеку, нужно загрузить код из библиотеки в пространство имен вашей программы. Пространство имен содержит функции, классы и переменные, доступные для программы. Если вы хотите вычислить синус угла, вам придется определить функцию, которая выполняет эти вычисления, или же загрузить готовую функцию. Встроенная библиотека math содержит функцию sin для вычисления синуса угла, выраженного в радианах. Библиотека также содержит переменную, определяющую значение «пи»:

>>> from math import sin, pi

>>> sin(pi/2)

1.0

Приведенный фрагмент загружает модуль math. Тем не менее он не помещает math в ваше пространство имен. Вместо этого он создает переменную, которая указывает на функцию sin из модуля math. Он также создает переменную, указывающую на переменную pi из модуля math. Если вы проанализируете текущее пространство имен при помощи функции dir, вы сможете убедиться в этом:

>>> 'sin' in dir()

True

24.1. Способы импортирования

В предыдущем примере мы импортировали одну функцию из библиотеки. Также можно загрузить библиотеку в пространство имен и обращаться ко всем классам, функциям и переменным. Чтобы импортировать модуль math в пространство имен, введите следующую команду:

>>> import math

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

>>> dir(math)

['__doc__', '__file__', '__loader__', '__name__',

'__package__', '__spec__', 'acos', 'acosh', 'asin',

'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign',

'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp',

'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp',

'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose',

'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log',

'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow',

'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

Большинство этих атрибутов составляют функции. Если вы хотите вызвать функцию tan, сделать это не удастся, потому что имя tan не входит в ваше пространство имен — только math. Однако вы можете провести поиск по переменной math с использованием оператора «точка» (.). Этот оператор просматривает атрибуты объекта. Так как в Python нет ничего, кроме объектов, вы можете воспользоваться этим оператором для поиска атрибута tan объекта math:

>>> math.tan(0)

0.0

518848.png 

Рис. 24.1. Импорт модуля. Обратите внимание, что этот код создает новую переменную math, которая указывает на модуль. Модуль имеет различные атрибуты, к которым вы можете получить доступ, использовав период

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

>>> help(math.tan)

Справка по встроенной функции tan в модуле math:

 

tan(...)

tan(x)

 

Возвращает тангенс x (в радианах).

СОВЕТ

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

>>> from math import sin, cos, tan

>>> cos(0)

1.0

Но если вам нужно обращаться к большей части библиотеки, будет проще импортировать библиотеку командой import. Такое решение также подскажет каждому, кто будет читать ваш код (включая вас), откуда взялась та или иная функция (класс, переменная).

ПРИМЕЧАНИЕ

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

>>> from math import sin,

... cos

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

SyntaxError: trailing comma not allowed

without surrounding parentheses

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

>>> from math import sin,\

... cos

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

>>> from math import (sin,

... cos)

Последняя форма считается более идиоматичной для Python.

24.2. Конфликты имен при импортировании

Если вы работаете над программой, выполняющей тригонометрические операции, у вас уже может быть определена функция с именем sin. А если вы также захотите использовать функцию sin из библиотеки math? Одно из возможных решений — импортировать math; тогда запись math.sin будет обозначать библиотечную версию, а sin — вашу функцию.

Python также предоставляет другую возможность. Вы можете переопределить импортируемое имя при помощи ключевого слова as:

>>> from math import sin as other_sin

>>> other_sin(0)

0.0

Теперь other_sin представляет собой ссылку на версию sin из math, а вы можете продолжать использовать sin без необходимости рефакторинга кода.

Ключевое слово as также работает с командами import. Если у вас имеется переменная (или функция), имя которой конфликтовало с именем из math в вашем пространстве имен, следующий фрагмент демонстрирует одно из возможных решений:

>>> import math as other_math

>>> other_math.sin(0)

0.0

СОВЕТ

Ключевое слово as также поможет сделать код более компактным. Если в вашей любимой библиотеке используются слишком длинные имена, вы можете легко сократить их в своем коде. Пользователи библиотеки Numpy приняли в качестве стандарта сокращенные имена из двух букв:

>>> import numpy as np

Аналогичный стандарт был принят в библиотеке Pandas:

>>> import pandas as pd

 

24.3. Массовое импортирование

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

>>> from math import *

>>> asin(0)

0.0

В этом коде вызывается функция арксинуса, которая не была определена в коде. Та строка, в которой вызывается asin, содержит первое упоминание asin в коде. Что произошло? Когда вы используете команду math import *, эта команда приказывает Python загрузить все содержимое библиотеки math (определения классов, функции и переменные) в локальное пространство имен. Хотя такая возможность на первый взгляд кажется удобной, на самом деле она довольно опасна.

Массовое импортирование усложняет отладку, потому что оно не выражает явно, откуда взялся тот или иной код. Еще больше проблем возникает с массовым импортированием из нескольких библиотек. Более поздние команды импортирования могут переопределить что-то такое, что было определено в более ранней библиотеке. По этой причине использовать массовое импортирование не рекомендуется.

СОВЕТ

Не используйте массовое импортирование!

Возможные исключения из этого правила встречаются разве что при самостоятельном написании кода тестирования или при экспериментах в REPL. Авторы библиотек применяют эту конструкцию для импортирования всего содержимого библиотеки, которую они собираются протестировать. Не используйте массовое импортирование только потому, что вы увидели его в чужом коде.

Вспомните Дзен Python:

«Явное лучше, чем неявное».

24.4. Вложенные библиотеки

У некоторых пакетов Python есть вложенное пространство имен. Например, библиотека XML, входящая в поставку Python, включает поддержку minidom и etree. Обе библиотеки размещаются внутри родительского пакета xml:

>>> from xml.dom.minidom import \

... parseString

>>> dom = parseString(

... '<xml><foo/></xml>')

 

>>> from xml.etree.ElementTree import \

... XML

>>> elem = XML('<xml><foo/></xml>')

Конструкция from позволяет импортировать только нужные функции и классы. Конструкция import (без from) увеличивает объем кода (но также открывает доступ ко всему содержимому пакета):

>>> import xml.dom.minidom

>>> dom = xml.dom.minidom.parseString(

... '<xml><foo/></xml>')

 

>>> import xml.etree.ElementTree

>>> elem = xml.etree.ElementTree.XML(

... '<xml><foo/></xml>')

24.5. Организация импортирования

Согласно PEP 8, команды импортирования должны располагаться в начале файла за строкой документации модуля. В каждой строке должна находиться одна команда import, причем команды import должны быть объединены в группы:

• Импортирование из стандартной библиотеки.

• Импортирование из стороннего кода.

• Импортирование из локальных пакетов.

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

#!/usr/bin/env python3

"""

Модуль преобразует записи в JSON

и сохраняет их в базе данных

"""

import json # Стандартные библиотеки

import sys

 

import psycopg2 # Сторонние библиотеки

 

import recordconverter # Локальные библиотеки

...

СОВЕТ

Сгруппированные команды импортирования удобно упорядочить по алфавиту.

СОВЕТ

Иногда команды импортирования бывает полезно отложить по следующим причинам:

• Для предотвращения циклического импортирования (ситуации, при которой модули импортируют друг друга). Если вы не можете (или не хотите) провести рефакторинг для предотвращения циклического импортирования, команду import можно разместить в функции или методе с тем кодом, из которого вызываются импортируемые элементы.

• Для предотвращения импортирования модулей, недоступных в некоторых системах.

• Для предотвращения импортирования больших модулей, не используемых в программе.

 

24.6. Итоги

В этой главе рассматривалось импортирование библиотек в Python. У Python имеется большая стандартная библиотека, и вам нужно будет импортировать эти библиотеки для использования в коде. В книге неоднократно подчеркивалось, что в Python нет ничего, кроме объектов, и вы часто создаете переменные, указывающие на эти объекты. При импортировании модуля создается переменная, указывающая на объект модуля. После этого вы можете обратиться к любым элементам пространства имен модуля при помощи операции поиска (.).

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

24.7. Упражнения

1. Найдите в стандартной библиотеке Python пакет для работы с JSON. Импортируйте библиотечный модуль и просмотрите атрибуты. Используйте функцию help для получения более подробной информации об использовании модуля. Сериализуйте словарь, связывающий ключ 'name' с вашим именем и ключ 'age' с вашим возрастом, в строку JSON. Проведите десериализацию JSON в Python.

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

numpy.org

pandas.pydata.org

Назад: 23. Исключения
Дальше: 25. Библиотеки: пакеты и модули