У меня есть функция генератора, которая делает 2 вещи:
Проблема в том, что я не всегда хочу делать пункт (2), и когда я вызываю его таким образом, что мне нужны только строки, записанные в новый файл, он просто не вызывается (т.е. оператор печати поскольку первая строка даже не получает вывод.
Я создал упрощенный тестовый пример, чтобы убедиться, что это «нормально», и он воспроизводит те же результаты.
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 определения, которые делают почти одно и то же, что нарушает принцип DRY. Поскольку в моем основном примере доходность вложена в «с открытым», это не то, что можно вытащить оттуда и сделать отдельно.
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))
.