Получить результат из функции downstream в генераторе - PullRequest
2 голосов
/ 10 июля 2019

Я изо всех сил пытаюсь выяснить, как добиться реализации, подобной следующей в python:

def a_generator():
    i = 0
    while True:
        yield i
        i += 1
        # if [downstream function returns false]:
        #     break
    cleanup()


def cleanup():
    # Do some cleanup task
    pass


def handle_each_value(i):
    if i > 10:
        return False
    return True


for value in a_generator():
    continue_processing = handle_each_value()
    # Cause the generator to run `cleanup()` if `continue_processing == False`

Есть ли способ сделать это, с помощью обратных вызовов или в качестве генератора?

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

С generator.close Характеристика:

def a_generator():
    i = 0
    try:
        while True:
            print('yield', i)
            yield i
            i += 1
    finally:
        cleanup()


def cleanup():
    # Do some cleanup task
    print('cleaned up')
    pass


def handle_each_value(i):
    if i > 10:
        return False
    return True

gen = a_generator()
for value in gen:
    continue_processing = handle_each_value(value)
    if not continue_processing:
        gen.close()

Пример вывода:

yield 0
yield 1
yield 2
yield 3
yield 4
yield 5
yield 6
yield 7
yield 8
yield 9
yield 10
yield 11
cleaned up
1 голос
/ 10 июля 2019

это версия: вы можете использовать cont = yield i внутри генератора, чтобы получить значение извне (которое отправляется gen.send(value)):

def a_generator():
    i = -1
    while True:
        cont = yield i
        if cont == False:
            break
        i += 1
    cleanup()

def cleanup():
    print("cleanup")

def handle_each_value(i):
    if i > 10:
        return False
    return True

gen = a_generator()
next(gen)  # need to prime the generator in order to call .send()
continue_processing = True
try:
    while True:
        value = gen.send(continue_processing)
        continue_processing = handle_each_value(value)
        print(value)
except StopIteration:
    pass
...