Контекстный менеджер, не возвращающий значения
Я хочу написать контекстный менеджер, который выглядит примерно так:
@contexlib.contextmanager
def process_started(process: mylib.Process) -> XXX: # ?
process.start()
try:
yield XXX # ?
except BaseException as e:
raise e # reraise any exception
finally:
process.finish()
То есть ему не надо возвращать какое-то значение, должен использоваться так:
with process_started(process):
do_background_stuff()
Что в таком случае надо указывать вместо XXX? Какой возвращаемый тип и значение у yield?
Ответы (3 шт):
Ничего не возвращайте. В аннотации укажите None. yield поддерживает такой синтаксис (который не отличается от yield None):
import contextlib
@contextlib.contextmanager
def f():
print('before')
yield
print('after')
with f():
print('within')
$ python yield.py before within after
yield действительно эквивалентно yield None, однако правильной аннотацией будет typing.Generator[None, None, None] (вместо None допустим его тип, но принято None писать), иначе тот же PyCharm будет подчёркивать ваши вызовы next() и send(). Возможный вариант без подчёркиваний typing.NoReturn, но, судя по комментам https://stackoverflow.com/a/36797437, его не принято использовать в такой ситуации.
Вместо typing.Generator[None, None, None] с Python 3.9 лучше использовать collections.abc.Generator[None, None, None]