Генераторная функция, которая всегда обрабатывает, но не всегда дает

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

  1. Читает файл и записывает другой файл на основе вывода.
  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. Поскольку в моем основном примере доходность вложена в «с открытым», это не то, что можно вытащить оттуда и сделать отдельно.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
40
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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)).

Другие вопросы по теме