Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Python 'with' statement with sys.stdout

I always open and write into files using with statement:

with open('file_path', 'w') as handle:
    print >>handle, my_stuff

However, there is one instance where I need to be able to be more flexible, and write to sys.stdout (or other types of streams), if that is provided instead of file path:

So, my question is this: Is there a way for using with statement both with real files and with sys.stdout?

Note that I can use the following code, but I think this defeats the purpose of using with:

if file_path != None:
    outputHandle = open(file_path, 'w')
else:
    outputHandle = sys.stdout

with outputHandle as handle:
    print >>handle, my_stuff
like image 846
farmir Avatar asked Mar 08 '14 03:03

farmir


People also ask

What does Sys stdout do in Python?

stdout. A built-in file object that is analogous to the interpreter's standard output stream in Python. stdout is used to display output directly to the screen console.

Does Python print to stdout?

The Python print() function takes in python data such as ints and strings, and prints those values to standard out. To say that standard out is "text" here means a series of lines, where each line is a series of chars with a '\n' newline char marking the end of each line.

What is SYS stdout flush () in Python?

flush() forces it to “flush” the buffer, meaning that it will write everything in the buffer to the terminal, even if normally it would wait before doing so. The sys module provides functions and variables used to manipulate different parts of the Python runtime environment.


2 Answers

You can create a context manager and use it like this

import contextlib, sys

@contextlib.contextmanager
def file_writer(file_name = None):
    # Create writer object based on file_name
    writer = open(file_name, "w") if file_name is not None else sys.stdout
    # yield the writer object for the actual use
    yield writer
    # If it is file, then close the writer object
    if file_name != None: writer.close()

with file_writer("Output.txt") as output:
    print >>output, "Welcome"

with file_writer() as output:
    print >>output, "Welcome"

If you don't pass any input to file_writer it will use sys.stdout.

like image 132
thefourtheye Avatar answered Oct 17 '22 05:10

thefourtheye


Thing is, you don't need to use a context processor with stdout, because you're not opening or closing it. A less fancy way of abstracting this is:

def do_stuff(file):
    # Your real code goes here. It works both with files or stdout
    return file.readline()

def do_to_stdout():
    return do_stuff(sys.stdout)

def do_to_file(filename):
    with open(filename) as f:
        return do_stuff(f)


print do_to_file(filename) if filename else do_to_stdout()
like image 36
slezica Avatar answered Oct 17 '22 06:10

slezica