Открытие нескольких файлов на основе условных выражений с помощью одного оператора with

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

Я знаю, что могу использовать оператор with для открытия нескольких файлов, например:

with open('log.txt', 'w') as logfile, open('out_a.txt', 'w') as out_a, open('out_b.txt', 'w') as out_b:
    # do something with logfile, out_a and out_b
# all files are closed here

Я хочу запустить аналогичную инструкцию, но открывать только определенные файлы на основе их соответствующих флагов. Я думал о том, чтобы реализовать это как conditional_openфункцию, что-то вроде:

write_log = True
write_out_a = False
write_out_b = True

with conditional_open('log.txt', 'w', cond=write_log) as logfile, open('out_a.txt', 'w', cond=write_out_a) as out_a, open('out_b.txt', 'w', cond=write_out_b) as out_b:
    # do something with logfile, out_a and out_b
# all files are closed here

Но я немного запутался в том, как правильно создать эту функцию. В идеале coditional_open либо возвращает дескриптор открытого файла, либо None (в этом случае файл никогда не создается / не затрагивается / не удаляется):

def conditional_open(filename, mode, cond):
    return open(filename, mode) if cond else None

Но я боюсь, что это упускает из виду преимущества диспетчера контекста при открытии файла, поскольку я вызываю open извне. Верно ли это предположение?

Может ли кто-нибудь дать несколько идей о том, как я могу это сделать? Я знаю, что могу создать фиктивные файловые объекты на основе условий и вместо этого писать в них, но для меня это звучит слишком запутанно - это кажется простой проблемой, которая должна иметь простое решение в Python. .


person jfaccioni    schedule 20.11.2019    source источник


Ответы (1)


Просто настройте свою функцию как диспетчер контекста.

from contextlib import contextmanager

@contextmanager
def conditional_open(f_name, mode, cond):
    if not cond:
        yield None
    resource = open(f_name, mode)
    try:
        yield resource
    finally:
        resource.close()
person alexisdevarennes    schedule 20.11.2019