Мне нравится общая идиома использования диспетчера контекста, но (слишком) тривиальное решение заканчивается закрытием sys.stdin
, когда вы выходите за пределы оператора with
, которого я хочу избежать.
Заимствование из этого ответа , вот обходной путь:
import sys
import contextlib
@contextlib.contextmanager
def _smart_open(filename, mode='Ur'):
if filename == '-':
if mode is None or mode == '' or 'r' in mode:
fh = sys.stdin
else:
fh = sys.stdout
else:
fh = open(filename, mode)
try:
yield fh
finally:
if filename is not '-':
fh.close()
if __name__ == '__main__':
args = sys.argv[1:]
if args == []:
args = ['-']
for filearg in args:
with _smart_open(filearg) as handle:
do_stuff(handle)
Полагаю, вы могли бы достичь чего-то похожего с os.dup()
, но код, который я подготовил для этого, оказался более сложным и более волшебным, тогда как вышеприведенное несколько неуклюже, но очень просто.