Функция генератора, которая всегда обрабатывает, но не всегда дает - PullRequest
2 голосов
/ 08 апреля 2019

У меня есть функция генератора, которая делает 2 вещи:

  1. Считывает файл и записывает другой файл на основе выходных данных.
  2. Возвращает ключевые значения для только что записанной записи.

Проблема в том, что я не всегда хочу указывать пункт (2), и когда я вызываю его так, что мне нужны только строки, записанные в новый файл, он просто не вызывается (т.е. оператор print в качестве первой строки даже не получает вывод.

Я создал упрощенный тестовый пример, чтобы убедиться, что это «нормально», и он воспроизводит те же результаты.

test.py

from test2 import run_generator

if __name__ == '__main__':
    print('*** Starting as generator ***')
    for num in run_generator(max=10, generate=True):
        print(f'Calling  : {num}')

    print('*** Starting without yielding ***')
    run_generator(max=10, generate=False)

    print('*** Finished ***')

test2.py

def run_generator(max, generate):
    print('*** In the generator function ***')
    sum = 1
    for i in range(max):
        print(f'Generator: {i}')
        sum += i

        if generate:
            yield i

    print(f'End of generator, sum={sum}')

Это дает мне вывод:

$ python3 test.py
*** Starting as generator ***
*** In the generator function ***
Generator: 0
Calling  : 0
Generator: 1
Calling  : 1
Generator: 2
Calling  : 2
Generator: 3
Calling  : 3
Generator: 4
Calling  : 4
Generator: 5
Calling  : 5
Generator: 6
Calling  : 6
Generator: 7
Calling  : 7
Generator: 8
Calling  : 8
Generator: 9
Calling  : 9
End of generator, sum=46
*** Starting without yielding ***
*** Finished ***

В тестовом примере я бы хотел, чтобы функция генератора по-прежнему печатала значения при вызове, но говорила не давать. (В моем реальном примере я все еще хочу, чтобы он выполнял функцию f.write () для другого файла, в который все вложено, поскольку это оператор with open(file, 'w') as f:.

Прошу ли я сделать что-нибудь глупое? Альтернатива, кажется, 2 определения, которые делают почти то же самое, что нарушает принцип СУХОЙ Так как в моем основном примере выход вложен в «с открытым», это не то, что можно вытащить оттуда и сделать отдельно.

1 Ответ

1 голос
/ 08 апреля 2019

it simply doesn't get called - это потому, что вы этого не называете.Для решения проблемы назовите его как любой другой генератор.Например, как вы сделали в первом случае: for num in run_generator(max=10, generate=False): pass.

Я полагаю, другой способ - использовать синтаксис next(run_generator(max=10, generate=False)) внутри try/except, поскольку yield никогда не достигается, поэтому вы получите StopIteration ошибка.

Или что-то вроде result = list(run_generator(5, True/False)).

...