Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Современные средства разработки программного обеспечения. Учебное пособие

.pdf
Скачиваний:
1
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
61
Итерация в Python может повторяться несколько раз, но итераторы вызывают ошибку StopIteration, когда все элементы уже повторены.
Пример.
num_list = [1, 2, 3, 4, 5]
itr = iter(num_list)
print(next(itr))
1
print(next(itr))
2
print(next(itr))
3
print(next(itr))
4
print(next(itr))
5
print(next(itr))
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
print(next(itr))
for i in num_list:
print(i)
1
2
3
4
5
5.2 Итерирование с помощью цикла for
Python позволяет «вручную» итерироваться по итераторам и итерируемым объ­ектам с помощью iter() и next() [21]. Однако, цикл for в Python является
встроенной поддержкой для автоматического итерирования:
for item in iterable:
# Выполнить какое-то действие над `item`, например вывести
62
print(item)
Если проигнорировать семантику с использова­нием continue, break и else, то цикл for в общем виде может быть записан
как:
for TARGET in ITER:
BLOCK
Что является синтаксическим сахаром для чего-то вроде:
iterable = (ITER)
iterator = iter(iterable)
running = True
while running:
try:
TARGET = next(iterator)
except StopIteration:
running = False
else:
BLOCK
Цикл for имеет специальную обработку для StopIteration. Цикл for поддержи­вает концепцию протокола итератор (iterator protocol) [22] и знает как поймать исклю­чение StopIteration и интерпретирует его как конец итерирования:
for item in RangeIterable(2):
print(item)
0
1
5.3 Генераторы
Генератор – это итератор, элементы которого можно перебирать (итерировать) только один раз.
Любая функция в Python, в теле которой встречается ключевое слово yield, называется генераторной функцией – при вызове она возвращает объект-генератор.
Вместо ключевого слова return в генераторе используется yield.
Объект-генератор
63
Функции генератора Python возвращают объект-генератор, который является итеративным, т. е. может использоваться как итератор. Объекты-генераторы ис­пользуются либо путем вызова следующего метода объекта-генератора, либо с ис­пользованием объекта-генератора в цикле for in.
Пример. Функция-генератор, которая возводит числа в куб:
def gencubes(n):
for x in range(n):
yield x**3
Здесь каждый раз получают лишь одно значение, всю последовательность од­новременно в списке не хранят, используют память более эффективно. Особенно за­метно при работе с Big Data.
for x in gencubes(10):
print(x)
0
1
8
27
64
125
216
343
512
729
gencubes не хранит в памяти список, каждый раз выводит лишь одно значение.
Чтобы получить результат в виде списка можно использовать list(gencubes(10))
Функции-генераторы – это функции, которые возвращают значение и затем мо- гут продолжить работу с того места, где они остановились в предыдущий раз.
В результате генераторы позволяют генерировать последовательности значе­ний постепенно, не создавая всю последовательность единовременно в памяти.
При первом исполнении кода тела функции код будет выполнен с начала и до первого встретившегося оператора yield. После этого будет возвращено первое значе­ние и выполнение тела функции опять приостановлено.
64
Запрос следующего значения у генератора во время итерации заставит код тела функции выполняться дальше (с предыдущего yield’а), пока не встретится следую­щий yield. Генератор считается «закончившимся» в случае если при очередном ис­полнении кода тела функции не было встречено ни одного оператора yield.
Выделяют:
− выражение-генератор (generator expression) — выражение в круглых скоб-
ках которое выдает создает на каждой итерации новый элемент по правилам.
− генератор коллекции — обобщенное название для генератора списка (list
comprehension), генератора словаря (dictionary comprehension) и генератора множе­ства (set comprehension)
Синтаксис выражения генератора
Выражение генератора в Python имеет следующий синтаксис:
(expression for item in iterable)
Пример. Создать объект-генератор, который будет печатать числа, кратные 5, в диапазоне от 0 до 5, которые также делятся на 2.
# generator expression generator_exp = (i * 5 for i in range(5) if i%2==0) for i in generator_exp: print(i)
Выход:
0
10
20
5.4 Модуль itertools
Python в своем определении допускает некоторые интересные и полезные функции итераторов для эффективного выполнения циклов и ускорения выполнения кода. В модуле «itertools» имеется множество встроенных итераторов. Этот модуль
65
реализует ряд строительных блоков итератора, вдохновленных конструкциями из APL, Haskell и SML. В модуле определены итераторы видов:
− Бесконечные итераторы.
− Итераторы, завершающиеся на кратчайшей входной последовательности.
− Комбинаторные итераторы.
Пример. Метод count([[начальное значение], [шаг]]) создает бесконечный ите- ратор, возвращающий числа от начального значения с некоторым шагом. По умолча­нию начального значение равно 0, а шаг равен 1.
import itertools
c3=itertools.count(1,-1.5)
print(next(c3)) #Output:1
print(next(c3)) #Output:-0.5
Пример. Метод combinations(p,r) возвращает кортежи r-длины, составленные из элементов итерируемого объекта p в отсортированном порядке, без повторяющихся элементов.
Пример. Метод dropwhile(predicate, iterable) создает итератор, который удаляет элементы из iterable до тех пор, пока predicate имеет значение true; после этого воз­вращает каждый элемент.
5.5 Контрольные вопросы
1 Каково основное назначение итераторов?
66
2 Что такое итерируемый объект?
3 Что такое итератор?
4 Опишите синтаксис функции iter().
5 Как цикл for реагирует на исключение StopIteration?
6 Что такое генератор?
7 Что такое генераторная функция?
8 Что возвращают генераторные функции в Python?
9 Какие выделяют подвиды генераторов?
10 Что содержится в модуле «itertools»?
67
6 Модульность, обработка исключений в Python
6.1 Модули, пакеты, библиотеки, фреймворки
Любой файл на Python является модулем, его имя является базовым именем файла без расширения .py. Внутри модуля имя модуля (в виде строки) доступно как значение глобальной переменной __name__.
Каждый модуль может содержать переменные, классы и функции, а также в мо- дуле может находиться исполняемый код.
Пакет – это набор модулей Python: в то время как модуль представляет собой один файл на Python. Пакет – это каталог модулей на Python, может содержать допол­нительный файл __init__.py, чтобы отличить пакет от каталога, который просто со­держит множество сценариев на Python. Начиная с версии 3.3+ Python поддерживает неявные пакеты пространства имен, что позволяет ему создавать пакеты без файла. Он называется пакетом пространства имен, в отличие от обычного пакета, в котором есть файл __init__.py (пустой или не пустой). Создание пакета пространства имен должно выполняться только в том случае, если в этом есть необходимость
Пакеты могут быть вложены на любую глубину.
Различие между модулем и пакетом, по-видимому, сохраняется только на уровне файловой системы. При импорте модуля или пакета, соответствующий объ­ект, созданный с помощью Python, всегда имеет тип module.
Пример.
Пакет xml входит в стандартную библиотеку Python: его каталог xml содержит файл __init__.py и четыре подкаталога; подкаталог etree содержит файл __init__.py и, среди прочих, файл ElementTree.py.
При попытке интерактивного импорта пакета/модулей видно следующее:
>>> import xml
>>> type(xml)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>>
68
>>>
>>> import xml.etree
>>> type(xml.etree)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>>
>>>
>>> import xml.etree.ElementTree
>>> type(xml.etree.ElementTree)
<type 'module'>
>>> xml.etree.ElementTree.parse
<function parse at 0x00B135B0>
Категории модулей
Все модули в Python можно разделить на:
– стандартная библиотека (от англ. standard library) [23];
– сторонние модули (от англ. 3rd party) – более 90 000 модулей и пакетов, ко- торые не входят в дистрибутив Python, но могут быть установлены из https://pypi.org/ официального сайта с помощью утилиты pip;
– пользовательские модули.
Импорт модулей и пакетов
Объекты из модуля/пакета могут быть импортированы в другие модули.
При импорте модуля Python выполняет весь код в нём.
При импорте пакета Python выполняет код в файле пакета __init__.py, если та­кой имеется.
Все объекты, определённые в модуле или __init__.py, становятся доступны им­портирующему коду.
Синтаксис импорта:
После ключевого слова import указывается название модуля. Одной инструк­цией можно подключить несколько модулей, хотя этого не рекомендуется делать.
69
После импортирования модуля его название становится переменной, через ко­торую можно получить доступ к атрибутам модуля.
Если название модуля слишком длинное, то для него можно создать псевдоним с помощью ключевого слова as.
При использовании псевдонима доступ ко всем атрибутам модуля осуществля­ется только с помощью переменной-псевдонима
Пример. Импорт стандартных модулей.
import time
import random
import os as windows_os
import math as m
print(time.time())
print(random.random())
print(windows_os.getcwd())
print(m.e)
Импорт через from
Инструкция from...import... чаще всего используется для частичного импорта.
from <модуль/пакет> import <атрибут/модуль_1> [as <псевдоним_1>],
[<атрибут/модуль_2>]
Пример.
# Импортируем функцию cos() из модуля math
from math import cos
print(math.cos(0))
1.0
# Импортируем число Пи из модуля math и дадим ему #псевдоним
from math import pi as number_pi
print(number_pi)
3.141592653589793
Поиск модуля интерпретатором
При импорте модуля интерпретатор ищет файл с именем my_module.py:
1 в текущем каталоге;
2 в каталогах, указанных в переменной окружения PYTHONPATH;
70
3 в зависящих от платформы путях по умолчанию, а также в специальных фай-
лах с расширением '.pth', которые лежат в стандартных каталогах.
Программист может внести изменения в PYTHONPATH и в '.pth', добавив туда свой путь. Каталоги, в которых осуществляется поиск, можно посмотреть в перемен­ной sys.path.
Запускаемые модули
Внутри модуля можно определить, используется ли он как модуль или как скрипт. Это позволяет запускать модуль самостоятельно и одновременно импортиро­вать его из другого кода.
Для запускаемых модулей нужно в код модуля добавить проверку следующего вида:
if __name__ == '__main__':
nameFunc()
При импорте модуля, его имя (сохраненное в переменной __name__) равно имени модуля. Когда выполняется скрипт, его имя всегда задается в виде строки '__main__'. Следовательно, проверив это имя, можно узнать, запущен ли скрипт или включен как модуль.
Библиотеки Python
Библиотека – это обобщающий термин, обозначающий повторно используемый фрагмент кода. Обычно библиотека Python содержит набор связанных модулей и па­кетов. На самом деле, этот термин часто используется как синоним “пакета Python”, потому что пакеты также могут содержать модули и другие пакеты (подпакеты). Од­нако часто предполагается, что, хотя пакет – это набор модулей, библиотека – это набор пакетов [24].
Часто разработчики создают библиотеки Python для обмена кодом многократ­ного использования с сообществом. Чтобы исключить необходимость написания кода с нуля, они создают набор полезных функций, относящихся к одной и той же области.
Фреймворки Python
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]