Search code examples
pythonstdinwith-statement

Idiomatic use of stdout as alternative


Is this idiomatic?

with open(output_file, 'w') if output_file else sys.stdout as outf:
    outf.write("hello")

Will the with block cause trouble to stdout (by closing it)?


Solution

  • If you try to write to stdout after that, it will:

    >>> import sys
    >>> output_file = None
    >>> with open(output_file, 'w') if output_file else sys.stdout as outf:
    ...     outf.write("hello")
    ... 
    hello5
    >>> print("test")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: I/O operation on closed file.
    

    The only way this could somehow safely be used would be as the last statement in a script where you know that stdout will not be used later, e.g:

    if __name__ == '__main__':
         output_file = ... # parse arguments
         with open(output_file, 'w') if output_file else sys.stdout as outf:
             outf.write("hello")
    

    But even that feels wrong. Better: separate opening and working with the file, and be explicit about it:

    if __name__ == '__main__':
         output_file = ... # parse arguments
         if output_file:
             with open(output_file, 'w') as outf:
                 do_stuff(outf)
         else:
                 do_stuff(sys.stdout)