SlideShare a Scribd company logo
1 of 43
Концепция сопрограмм
Александр Мокров
Асинхронность
«Подпрограммы — это частные случаи более общих программных
компонентов, называемых сопрограммами. В противоположность
несимметричной связи между главной программой и
подпрограммой, между сопрограммами, которые вызывают одна
другую, существует полная симметрия.»
«Искусство программирования» Д. Кнут
«A coroutine is similar to a procedure and a generator is similar to a
function. The principle difference between these program units and
procedures/functions is that the call/return mechanism is different.
Coroutines are especially useful for multiplayer games and other
program flow where sections of code "take turns" executing. Generators,
as their name implies, are useful for generating a sequence of values; in
many respects generators are quite similar to HLA’s iterators without all
the restrictions of the iterators »
«The Art of Assembly Language» by Randall Hyde
Подпрограммы
Сопрограммы
Coroutines
Disclaimers
Coroutines — одна из наиболее неясных
особенностей Python
Асинхронность и конкурентность — одни из
наиболее сложных тем в computer science
Основной фундамент заложен в 60-80 годы, но
работа в этом направлении была закончена в
пользу других альтернатив (threads,
continuations...)
Итераторы
Итерируемые объекты (iterables) - объект,
который реализует метод __iter__(),
возвращающий итератор.
Итератор — объект, реализующие метод
__next__()
class Letter:
def __init__(self):
self.current = 'a'
def __next__(self):
if self.current > 'd':
raise StopIteration
result = self.current
self.current = chr(ord(result)+1)
return result
def __iter__(self):
return self
>>> iletter = Letter()
>>> letter = iter(iletter)
>>> letter.__next__()
'a'
>>> letter.__next__()
'b'
>>> next(letter)
'c'
>>> next(letter)
'd'
>>> next(letter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "letter.py", line 7, in __next__
raise StopIteration
StopIteration
>>> letter = Letter()
>>> for l in letter:
... print(l)
...
a
b
c
d
>>> sum(letter)
0
For Statements
letter = Letter()
>>> i = letter.__iter__()
>>> try:
while True:
item = i.__next__()
print(item)
except StopIteration:
pass
a
b
c
d
PEP 255 -- Simple Generators
Authors:
Neil Schemenauer <nas at arctrix.com>,
Tim Peters <tim.peters at gmail.com>,
Magnus Lie Hetland <magnus at hetland.org>
Created: 18-May-2001
Python 2.2
>>> def letters_generator():
current = 'a'
while current <= 'd':
yield current
current = chr(ord(current)+1)
>>> for letter in letters_generator():
print(letter)
a
b
c
d
def countdown(n):
print("Counting down from", n)
while n > 0:
yield n
n -= 1
>>> x = countdown(10)
>>> x
<generator object countdown at 0x7fe8f9cd5318>
>>> next(x)
Counting down from 10
10
>>>
Генераторы
Прострой способ создания итераторов
,Простой синтаксис добавлено только
yieldключевое слово
Запоминаются состояния между вызовами
IconСтащили идею из
PEP 342 Coroutine via Enhanced Generators
Authors: Guido van Rossum, Phillip J. Eby
Created: 10-May-2005
Python 2.5
PEP 288, Generators Attributes and Exceptions
(Raymond Hettinger)
PEP 325, Resource-Release Support for Generators
(Samuele Pedroni)
Что добавилось
1. (yield) statement:
value = (yield)
2. send()
3. throw()
4. close()
5. Вызов close() сборщиком мусора
6. Разрешено использование yield внутри
try/finally блоков
>>> def match(pattern):
print('Ищем ' + pattern)
try:
while True:
s = (yield)
if pattern in s:
print(s)
except GeneratorExit:
print("=== Done ===")
>>> m = match("runnts")
>>> m.__next__()
Ищем runnts
>>> m.send("А про rannts - все очень просто.")
А про rannts - все очень просто.
>>> m.send("Две n - географическая привязка")
>>> m.send("rant - тирады, пустословие, помпезные речи,
бахвальство, декламация и шумная проповедь")
>>> m.close()
=== Done ===
Produce, Filter, and Consume
Producer
def read(text, next_coroutine):
for line in text.split():
next_coroutine.send(line)
next_coroutine.close()
Filter
def match_filter(pattern, next_coroutine):
print('Looking for ' + pattern)
try:
while True:
s = (yield)
if pattern in s:
next_coroutine.send(s)
except GeneratorExit:
next_coroutine.close()
Consumer
def print_consumer():
print('Preparing to print')
try:
while True:
line = (yield)
print(line)
except GeneratorExit:
print("=== Done ===")
>>> printer = print_consumer()
>>> printer.__next__()
Preparing to print
>>> matcher = match_filter('pend', printer)
>>> matcher.__next__()
Looking for pend
>>> read(text, matcher)
spending
pending
=== Done ===
PEP 380 Syntax for Delegating to a Subgenerator
Authors: Gregory Ewing
Created: 13-Feb-2009
Python 3.3
Новый оператор
RESULT = yield from EXPR
Теперь вместо
for v in g:
yield v
Можно писать
yield from g
def writer():
while True:
w = (yield)
print('>> ', w)
def writer_wrapper(coro):
pass
w = writer()
wrap = writer_wrapper(w)
wrap.send(None)
for i in range(4):
wrap.send(i)
# Expected result
>> 0
>> 1
>> 2
>> 3
def writer_wrapper(coro):
coro.send(None) # prime the coro
while True:
try:
x = (yield) # Capture the value that's sent
coro.send(x) # and pass it to the writer
except StopIteration:
pass
или
def writer_wrapper(coro):
yield from coro
class SpamException(Exception):
pass
def writer():
while True:
try:
w = (yield)
except SpamException:
print('***')
else:
print('>> ', w)
w = writer()
wrap = writer_wrapper(w)
wrap.send(None) # "prime" the coroutine
for i in [0, 1, 2, 'spam', 4]:
if i == 'spam':
wrap.throw(SpamException)
else:
wrap.send(i)
# Expected Result
>> 0
>> 1
>> 2
***
>> 4
# Actual Result
>> 0
>> 1
>> 2
Traceback (most recent call last):
... redacted ...
File ... in writer_wrapper
x = (yield)
__main__.SpamException
def writer_wrapper(coro):
"""Works. Manually catches exceptions and throws them"""
coro.send(None) # prime the coro
while True:
try:
try:
x = (yield)
except Exception as e: # This catches the SpamException
coro.throw(e)
else:
coro.send(x)
except StopIteration:
pass
# Result
>> 0
>> 1
>> 2
***
>> 4
def writer_wrapper(coro):
yield from coro
Пару слов об asyncio и сопрограммах в нем
PEP 0492 -- Coroutines with async and await
syntax
Authors: Yury Selivanov
Created: 09-Apr-2015
Python 3.5
New Coroutine Declaration Syntax
async def read_data(db):
pass
Await Expression
async def read_data(db):
data = await db.fetch('SELECT ...')
...
Asynchronous Context Managers and "async
with"
class AsyncContextManager:
async def __aenter__(self):
await log('entering context')
async def __aexit__(self, exc_type, exc, tb):
await log('exiting context')
async def commit(session, data):
...
async with session.transaction():
...
await session.update(data)
…
Код, требующий блокировки:
async with lock:
…
вместо:
with (yield from lock):
...
Asynchronous Iterators and "async for"
class Cursor:
def __init__(self):
self.buffer = collections.deque()
async def _prefetch(self):
...
async def __aiter__(self):
return self
async def __anext__(self):
if not self.buffer:
self.buffer = await self._prefetch()
if not self.buffer:
raise StopAsyncIteration
return self.buffer.popleft()
async for row in Cursor():
print(row)
https://www.python.org/dev/peps
http://wla.berkeley.edu/~cs61a/fa11/lectures/streams.
http://www.dabeaz.com/coroutines/
Ссылки
Спасибо!

More Related Content

What's hot

Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORMBadoo Development
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 
Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutinescorehard_by
 
Asyncio для процессинга распределенной базы данных
Asyncio для процессинга  распределенной базы данныхAsyncio для процессинга  распределенной базы данных
Asyncio для процессинга распределенной базы данныхPyNSK
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonPython Meetup
 
Михаил Давыдов — JavaScript: Асинхронность
Михаил Давыдов — JavaScript: АсинхронностьМихаил Давыдов — JavaScript: Асинхронность
Михаил Давыдов — JavaScript: АсинхронностьYandex
 
"Деплой кода процедур" Мурат Кабилов (Avito)
"Деплой кода процедур" Мурат Кабилов (Avito)"Деплой кода процедур" Мурат Кабилов (Avito)
"Деплой кода процедур" Мурат Кабилов (Avito)AvitoTech
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПzfconfua
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работуcorehard_by
 
Thumbtack Expertise Days # 5 - Ansible
Thumbtack Expertise Days # 5 - AnsibleThumbtack Expertise Days # 5 - Ansible
Thumbtack Expertise Days # 5 - AnsibleAlexey Remnev
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование LinuxAnthony Shoumikhin
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package managercorehard_by
 

What's hot (20)

Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Clojure #1
Clojure #1Clojure #1
Clojure #1
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORM
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Python infrastructure from scratch
Python infrastructure from scratchPython infrastructure from scratch
Python infrastructure from scratch
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutines
 
Asyncio для процессинга распределенной базы данных
Asyncio для процессинга  распределенной базы данныхAsyncio для процессинга  распределенной базы данных
Asyncio для процессинга распределенной базы данных
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки Python
 
Михаил Давыдов — JavaScript: Асинхронность
Михаил Давыдов — JavaScript: АсинхронностьМихаил Давыдов — JavaScript: Асинхронность
Михаил Давыдов — JavaScript: Асинхронность
 
"Деплой кода процедур" Мурат Кабилов (Avito)
"Деплой кода процедур" Мурат Кабилов (Avito)"Деплой кода процедур" Мурат Кабилов (Avito)
"Деплой кода процедур" Мурат Кабилов (Avito)
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работу
 
Thumbtack Expertise Days # 5 - Ansible
Thumbtack Expertise Days # 5 - AnsibleThumbtack Expertise Days # 5 - Ansible
Thumbtack Expertise Days # 5 - Ansible
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование Linux
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package manager
 

Similar to Coroutines

Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Dmitri Soshnikov
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотекPyNSK
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняAlexander Granin
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
1 вводное занятие
1 вводное занятие1 вводное занятие
1 вводное занятиеluis_blanco_rau
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадZheka Kozlov
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonovComputer Science Club
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20DefconRussia
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...OdessaFrontend
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.Roman Brovko
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp
 
Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Denis Zakharov
 
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelЛекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelMikhail Kurnosov
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеYandex
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомTatyanazaxarova
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософияPaul Klimov
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Mikhail Kurnosov
 
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Mikhail Kurnosov
 
Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Volodymyr Hotsyk
 

Similar to Coroutines (20)

Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...Функциональное программирование для разработки распределённых, облачных и веб...
Функциональное программирование для разработки распределённых, облачных и веб...
 
Мир Python функционалим с помощью библиотек
Мир Python  функционалим с помощью библиотекМир Python  функционалим с помощью библиотек
Мир Python функционалим с помощью библиотек
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
1 вводное занятие
1 вводное занятие1 вводное занятие
1 вводное занятие
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монад
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный Python
 
Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.Development of a plugin for VS Code that supports ACSL language.
Development of a plugin for VS Code that supports ACSL language.
 
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelЛекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
 
Иван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программированиеИван Пузыревский — Введение в асинхронное программирование
Иван Пузыревский — Введение в асинхронное программирование
 
Разница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментомРазница в подходах анализа кода компилятором и выделенным инструментом
Разница в подходах анализа кода компилятором и выделенным инструментом
 
Ф'Yii'лософия
Ф'Yii'лософияФ'Yii'лософия
Ф'Yii'лософия
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
 
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
Лекция 7: Фибоначчиевы кучи (Fibonacci heaps)
 
Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...Internationalization and localization of the python applications with gettext...
Internationalization and localization of the python applications with gettext...
 

Coroutines

  • 3. «Подпрограммы — это частные случаи более общих программных компонентов, называемых сопрограммами. В противоположность несимметричной связи между главной программой и подпрограммой, между сопрограммами, которые вызывают одна другую, существует полная симметрия.» «Искусство программирования» Д. Кнут «A coroutine is similar to a procedure and a generator is similar to a function. The principle difference between these program units and procedures/functions is that the call/return mechanism is different. Coroutines are especially useful for multiplayer games and other program flow where sections of code "take turns" executing. Generators, as their name implies, are useful for generating a sequence of values; in many respects generators are quite similar to HLA’s iterators without all the restrictions of the iterators » «The Art of Assembly Language» by Randall Hyde
  • 7.
  • 8. Disclaimers Coroutines — одна из наиболее неясных особенностей Python Асинхронность и конкурентность — одни из наиболее сложных тем в computer science Основной фундамент заложен в 60-80 годы, но работа в этом направлении была закончена в пользу других альтернатив (threads, continuations...)
  • 10. Итерируемые объекты (iterables) - объект, который реализует метод __iter__(), возвращающий итератор. Итератор — объект, реализующие метод __next__()
  • 11. class Letter: def __init__(self): self.current = 'a' def __next__(self): if self.current > 'd': raise StopIteration result = self.current self.current = chr(ord(result)+1) return result def __iter__(self): return self
  • 12. >>> iletter = Letter() >>> letter = iter(iletter) >>> letter.__next__() 'a' >>> letter.__next__() 'b' >>> next(letter) 'c' >>> next(letter) 'd' >>> next(letter) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "letter.py", line 7, in __next__ raise StopIteration StopIteration >>> letter = Letter() >>> for l in letter: ... print(l) ... a b c d >>> sum(letter) 0
  • 13. For Statements letter = Letter() >>> i = letter.__iter__() >>> try: while True: item = i.__next__() print(item) except StopIteration: pass a b c d
  • 14. PEP 255 -- Simple Generators Authors: Neil Schemenauer <nas at arctrix.com>, Tim Peters <tim.peters at gmail.com>, Magnus Lie Hetland <magnus at hetland.org> Created: 18-May-2001 Python 2.2
  • 15. >>> def letters_generator(): current = 'a' while current <= 'd': yield current current = chr(ord(current)+1) >>> for letter in letters_generator(): print(letter) a b c d
  • 16. def countdown(n): print("Counting down from", n) while n > 0: yield n n -= 1 >>> x = countdown(10) >>> x <generator object countdown at 0x7fe8f9cd5318> >>> next(x) Counting down from 10 10 >>>
  • 17.
  • 18. Генераторы Прострой способ создания итераторов ,Простой синтаксис добавлено только yieldключевое слово Запоминаются состояния между вызовами IconСтащили идею из
  • 19. PEP 342 Coroutine via Enhanced Generators Authors: Guido van Rossum, Phillip J. Eby Created: 10-May-2005 Python 2.5 PEP 288, Generators Attributes and Exceptions (Raymond Hettinger) PEP 325, Resource-Release Support for Generators (Samuele Pedroni)
  • 20. Что добавилось 1. (yield) statement: value = (yield) 2. send() 3. throw() 4. close() 5. Вызов close() сборщиком мусора 6. Разрешено использование yield внутри try/finally блоков
  • 21. >>> def match(pattern): print('Ищем ' + pattern) try: while True: s = (yield) if pattern in s: print(s) except GeneratorExit: print("=== Done ===") >>> m = match("runnts") >>> m.__next__() Ищем runnts >>> m.send("А про rannts - все очень просто.") А про rannts - все очень просто. >>> m.send("Две n - географическая привязка") >>> m.send("rant - тирады, пустословие, помпезные речи, бахвальство, декламация и шумная проповедь") >>> m.close() === Done ===
  • 23. Producer def read(text, next_coroutine): for line in text.split(): next_coroutine.send(line) next_coroutine.close()
  • 24. Filter def match_filter(pattern, next_coroutine): print('Looking for ' + pattern) try: while True: s = (yield) if pattern in s: next_coroutine.send(s) except GeneratorExit: next_coroutine.close()
  • 25. Consumer def print_consumer(): print('Preparing to print') try: while True: line = (yield) print(line) except GeneratorExit: print("=== Done ===")
  • 26. >>> printer = print_consumer() >>> printer.__next__() Preparing to print >>> matcher = match_filter('pend', printer) >>> matcher.__next__() Looking for pend >>> read(text, matcher) spending pending === Done ===
  • 27. PEP 380 Syntax for Delegating to a Subgenerator Authors: Gregory Ewing Created: 13-Feb-2009 Python 3.3
  • 28. Новый оператор RESULT = yield from EXPR Теперь вместо for v in g: yield v Можно писать yield from g
  • 29. def writer(): while True: w = (yield) print('>> ', w) def writer_wrapper(coro): pass w = writer() wrap = writer_wrapper(w) wrap.send(None) for i in range(4): wrap.send(i) # Expected result >> 0 >> 1 >> 2 >> 3
  • 30. def writer_wrapper(coro): coro.send(None) # prime the coro while True: try: x = (yield) # Capture the value that's sent coro.send(x) # and pass it to the writer except StopIteration: pass или def writer_wrapper(coro): yield from coro
  • 31. class SpamException(Exception): pass def writer(): while True: try: w = (yield) except SpamException: print('***') else: print('>> ', w)
  • 32. w = writer() wrap = writer_wrapper(w) wrap.send(None) # "prime" the coroutine for i in [0, 1, 2, 'spam', 4]: if i == 'spam': wrap.throw(SpamException) else: wrap.send(i) # Expected Result >> 0 >> 1 >> 2 *** >> 4 # Actual Result >> 0 >> 1 >> 2 Traceback (most recent call last): ... redacted ... File ... in writer_wrapper x = (yield) __main__.SpamException
  • 33. def writer_wrapper(coro): """Works. Manually catches exceptions and throws them""" coro.send(None) # prime the coro while True: try: try: x = (yield) except Exception as e: # This catches the SpamException coro.throw(e) else: coro.send(x) except StopIteration: pass # Result >> 0 >> 1 >> 2 *** >> 4
  • 35. Пару слов об asyncio и сопрограммах в нем
  • 36. PEP 0492 -- Coroutines with async and await syntax Authors: Yury Selivanov Created: 09-Apr-2015 Python 3.5
  • 37. New Coroutine Declaration Syntax async def read_data(db): pass
  • 38. Await Expression async def read_data(db): data = await db.fetch('SELECT ...') ...
  • 39. Asynchronous Context Managers and "async with" class AsyncContextManager: async def __aenter__(self): await log('entering context') async def __aexit__(self, exc_type, exc, tb): await log('exiting context')
  • 40. async def commit(session, data): ... async with session.transaction(): ... await session.update(data) … Код, требующий блокировки: async with lock: … вместо: with (yield from lock): ...
  • 41. Asynchronous Iterators and "async for" class Cursor: def __init__(self): self.buffer = collections.deque() async def _prefetch(self): ... async def __aiter__(self): return self async def __anext__(self): if not self.buffer: self.buffer = await self._prefetch() if not self.buffer: raise StopAsyncIteration return self.buffer.popleft() async for row in Cursor(): print(row)