Возможно ли иметь необязательный оператор /as в python?

Вместо этого:

FILE = open(f)
do_something(FILE)
FILE.close()

лучше использовать это:

with open(f) as FILE:
    do_something(FILE)

Что делать, если у меня есть что-то вроде этого?

if f is not None:
   FILE = open(f)
else:
   FILE = None
do_something(FILE)
if FILE is not None:
    FILE.close()

Где do_something также имеет предложение if, если FILE is None, и все же делает что-то полезное в этом случае - я не хочу просто пропустить do_something, если FILE - None.

Есть ли разумный способ превратить это в/в форму? Или я просто пытаюсь решить проблему с дополнительными файлами неправильно?

Ответ 1

Если вы просто напишете это так:

if f is not None:
    with open(f) as FILE:
        do_something(FILE)
else:
    do_something(f)

(file является встроенным btw)

Обновление

Вот забавный способ сделать "на лету" контекст с необязательным "Нет", который не сработает:

from contextlib import contextmanager

none_context = contextmanager(lambda: iter([None]))()
# <contextlib.GeneratorContextManager at 0x1021a0110>

with (open(f) if f is not None else none_context) as FILE:
    do_something(FILE)

Создает контекст, который возвращает значение None. with будет либо производить FILE в качестве файлового объекта, либо тип None. Но тип None будет иметь правильный __exit__

Ответ 2

Это, похоже, решает все ваши проблемы.

if file_name is not None:
    with open(file_name) as fh:
        do_something(fh)
else:
        do_something(None)

Ответ 3

что-то вроде:

if file:      #it checks for None,false values no need of "if file is None"
    with open(file) as FILE:
        do_something(FILE)
else:
    FILE=None

Ответ 4

В то время как все остальные ответы превосходны и предпочтительны, обратите внимание, что выражение with может быть любым выражением, поэтому вы можете:

with (open(file) if file is not None else None) as FILE:
    pass

Обратите внимание: если выражение else было оценено, чтобы получить None, это приведет к исключению, потому что NoneType не поддерживает соответствующие операции, которые будут использоваться в качестве менеджера контекста.

Ответ 5

Начиная с Python 3.7, вы также можете сделать

from contextlib import nullcontext

with (open(file) if file else nullcontext()) as FILE:
    # Do something with 'FILE'
    pass

Смотрите официальную документацию для более подробной информации.