Python context for file or None

Python will call the subprocess, the user either requested that the stdout subprocesses go to the file (or back to os.devnull), or the output of the subprocesses should be transmitted, although "in real time".

My last best guess on how to do this seems to work:

  • Let a file_pathvalid input foropen()
  • Let it be logginga boolean indicator, true indicates use file_pathfor logging or false for passthough to stdout.

with open(file_path, 'wb') if logging else None as shell_stdout:
    subprocess.call(['ls'], stdout=shell_stdout)

When transcoding / testing, this turns out to be the correct value, which I assumed worked well with subprocess.call. However, and not surprisingly, I get the following exception:

AttributeError: __exit__

So, Noneit is not a context; it does not have __exit__;


Goals

  • , .
  • ( stdlib), (: , / .)
  • / ( )
  • subprocesses.call ( )

, ? /?

+4
3

:

import subprocess
import contextlib
@contextlib.contextmanager
def noop():
    yield None

logging = False
file_path = '/tmp/out'

with open(file_path, 'wb') if logging else noop() as shell_stdout:
    subprocess.call(['ls'], stdout=shell_stdout)

True . logging False, noop() ( with-statement), shell_out None, .


, stdout=None,

... ; childs .

stdout sys.stdout. , sys.stdout , (, sys.stdout = open('/tmp/stdout', 'wb')), , , , sys.stdout. , fileinput sys.stdout. noop() stdout stdout, sys.stdout.

, Padraic Cunningham solution :

with open(file_path, 'wb') if logging else sys.stdout as shell_stdout:
    subprocess.call(['ls'], stdout=shell_stdout)
+7

shell_stdout stdout, file object , True False, , if logging True, False, , with, , with .

import sys

if logging:
      shell_stdout = open(file_path, 'wb') # to file or devnull if logging
else:
    shell_stdout = sys.stdout
subprocess.call(['ls'], stdout=shell_stdout) # real time if not logging
shell_stdout.close()

, , : bar sys.stdout:

with open(file_path, 'wb') if logging else sys.stdout as shell_stdout:
    subprocess.call(['ls'], stdout=shell_stdout)

, True.

+3

Starting in Python 3.3, tou can define a no-op context manager using contextlib.ExitStack:

from contextlib import ExitStack

with open(...) if ... else ExitStack():
    ...
0
source

All Articles