Б41 Чистый Python. Тонкости программирования для профи. Спб.: Питер



Download 6,94 Mb.
Pdf ko'rish
bet70/80
Sana24.02.2022
Hajmi6,94 Mb.
#212875
1   ...   66   67   68   69   70   71   72   73   ...   80
Bog'liq
978544610803 Chisty Python Tonko

'Всем привет' 
'Всем привет' 
'Всем привет'
Как вы, возможно, и ожидали, этот генератор прекратил порождать новые 
значения после трех итераций. Можно предположить, что он это сделал 
путем вызова исключения 
StopIteration
, когда исполнение достигло 
конца функции. Но чтобы быть до конца уверенными, давайте подтвердим 
это еще одним экспериментом:
>>> iterator = repeat_three_times('Всем привет') 
>>> next(iterator) 
'Всем привет' 
>>> next(iterator) 


6 .5 . Генераторы — это упрощенные итераторы 229
'Всем привет' 
>>> next(iterator) 
'Всем привет' 
>>> next(iterator) 
StopIteration 
>>> next(iterator) 
StopIteration 
Этот итератор вел себя именно так, как мы и ожидали. Как только мы до-
стигаем конца функции-генератора, он начинает вызывать 
StopIteration

сигнализируя о том, что у него больше нет значений, которые он мог бы 
предоставить.
Давайте вернемся к еще одному примеру из раздела об итераторах. Класс 
BoundedIterator
реализовал итератор, который будет повторять значение, 
заданное определенное количество раз:
class BoundedRepeater:
def __init__(self, value, max_repeats):
self.value = value
self.max_repeats = max_repeats
self.count = 0 
def __iter__(self):
return self 
def __next__(self):
if self.count >= self.max_repeats:
raise StopIteration
self.count += 1
return self.value
Почему бы не попробовать реализовать класс 
BoundedRepeater
заново как 
функцию-генератор? Сделаю первую попытку:
def bounded_repeater(value, max_repeats):
count = 0
while True:
if count >= max_repeats:
return
count += 1
yield value


230 Глава 6 • Циклы и итерации
Я преднамеренно сделал цикл 
while
в этой функции несколько громозд-
ким. Я хотел продемонстрировать, как вызов инструкции 
return
из ге-
нератора приводит к остановке итераций с исключением 
StopIteration

Мы вскоре подчистим и еще немного упростим эту функцию-генератор, 
но сначала давайте испытаем то, что у нас есть сейчас:
>>> for x in bounded_repeater('Привет', 4):
... print(x) 
'Привет'
'Привет' 
'Привет' 
'Привет'
Великолепно! Теперь у нас есть генератор, который прекращает по-
рождать значения после настраиваемого количества повторений. Он 
использует инструкцию 
yield
, чтобы передавать значения назад до тех 
пор, пока он наконец не натолкнется на инструкцию 
return
и итерации 
не прекратятся.
Как я вам обещал, мы можем упростить этот генератор еще больше. Мы 
воспользуемся тем, что в конец каждой функции Python добавляет не-
явную инструкцию 
return
None
. И вот как будет выглядеть наша оконча-
тельная реализация:
def bounded_repeater(value, max_repeats):
for i in range(max_repeats):
yield value
Не стесняйтесь подтвердить, что этот упрощенный генератор по-
прежнему работает таким же образом. Учитывая все обстоятельства, мы 
прошли путь от 12-строчной реализации в классе 
BoundedRepeater
до 
трехстрочной реализации на основе генератора, обеспечив ту же самую 
функциональность. А это 75 %-ное сокращение количества строк кода — 
нехило!
Как вы только что убедились, генераторы помогают «абстрагироваться 
от» большей части шаблонного кода, который в других обстоятельствах 
был бы необходим во время написания итераторов на основе класса. Они 
способны очень облегчить вашу программистскую жизнь и позволяют 


6 .6 . Выражения-генераторы 231
писать более чистые, короткие и удобные в сопровождении итераторы. 
Функции-генераторы представляют собой отличное функциональное 
средство языка Python, и вам следует решительно и смело использовать 
их в своих собственных программах.
Ключевые выводы
‰
‰
Функции-генераторы являются синтаксическим сахаром для написа-
ния объектов, которые поддерживают протокол итератора. Генераторы 
абстрагируются от большей части шаблонного кода, необходимого во 
время написания итераторов на основе класса.
‰
‰
Инструкция 
yield
позволяет временно приостанавливать исполнение 
функции-генератора и передавать из него значения назад.
‰
‰
Генераторы начинают вызывать исключения 
StopIteration
после того, 
как поток управления покидает функцию-генератор каким-либо иным 
способом, кроме инструкции 
yield
.
6 .6 . Выражения-генераторы
По мере того как я все больше узнавал о протоколе итератора Python 
и различных способах его реализации в собственном коде, я стал пони-
мать, что синтаксический сахар является повторяющейся темой.
Дело в том, что итераторы на основе класса и функции-генераторы вы-
ражают один и тот же лежащий в основе шаблон проектирования.
Функции-генераторы предоставляют краткую форму для поддержки 
протокола итератора в своем собственном коде и по большей части 
избегают многословности итераторов на основе класса. Благодаря не-
значительному объему специализированного синтаксиса или «горсти» 

Download 6,94 Mb.

Do'stlaringiz bilan baham:
1   ...   66   67   68   69   70   71   72   73   ...   80




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish