Запуск сопрограммы начинается с send (), а не next () - PullRequest
0 голосов
/ 01 ноября 2018

Я изучаю сопрограмму из удивительной презентации Дэвида Бизли. Сопрограмма

Я очень смущен простым примером задачи, в котором генератор запускается без продолжения next()

class Task(object):
    taskid = 0
    def __init__(self, target):
        Task.taskid += 1
        self.tid    = Task.taskid #Task id
        self.target = target      #Target coroutine
        self.sendval = None  #value to send

    def run(self):
        return self.target.send(self.sendval)

# a very simple generator

def foo():
    print('Part 1')
    yield
    print("Part 2")
    yield

начинается без следующего ()

In [8]: t1 = Task(foo())                                                                                          
In [9]: t1.run()                                                                                                  
Part 1

Что касается foo

In [10]: f1 = foo()                                                                                               

In [11]: f1.send(1)                                                                                               
TypeError: can't send non-None value to a just-started generator

Должен начинаться с next() заранее.

Как я мог понять эту ситуацию?

1 Ответ

0 голосов
/ 01 ноября 2018

Описание ошибки говорит вам, что не так и что вы должны сделать - вы должны отправить None только что созданному генератору. Это f1.send(None) вместо f1.send(1). Обычно сопрограммы используются с декоратором, как тот, который вы указали в вопросе (класс Task и его метод run), или как следующий:

def coroutine(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        generator = func(*args, **kwargs)
        next(generator)
        return generator
    return wrapper
...