[英]using Python 'with' statement with sys.stdout
I always open and write into files using with
statement:我总是使用with
语句打开并写入文件:
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:但是,在一个实例中,我需要能够更加灵活,并写入sys.stdout
(或其他类型的流),如果提供的是文件路径而不是文件路径:
So, my question is this: Is there a way for using with
statement both with real files and with sys.stdout
?所以,我的问题是:有没有办法同时使用with
语句和真实文件和sys.stdout
?
Note that I can use the following code, but I think this defeats the purpose of using with
:请注意,我可以使用以下代码,但我认为这违背了使用with
的目的:
if file_path != None:
outputHandle = open(file_path, 'w')
else:
outputHandle = sys.stdout
with outputHandle as handle:
print >>handle, my_stuff
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
.如果您不将任何输入传递给file_writer
,它将使用sys.stdout
。
Thing is, you don't need to use a context processor with stdout
, because you're not opening or closing it.问题是,您不需要将上下文处理器与stdout
一起使用,因为您没有打开或关闭它。 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()
The simplest way is to simply use "old school" streamed filenames, that way your code doesn't have to change.最简单的方法是简单地使用“老派”流文件名,这样您的代码就不必更改。 In Unix this is "/dev/tty" or in Windows this is "con" (although there are other choices for both platforms).在 Unix 中这是“/dev/tty”,在 Windows 中是“con”(尽管两个平台都有其他选择)。
if default_filename is None:
default_filename = "/dev/tty"
with open(default_filename, 'w') as handle:
handle.write("%s\n" % my_stuff)
This code tested in Python 2.7.3 and 3.3.5此代码在 Python 2.7.3 和 3.3.5 中测试
With python3 optional closefd
argument is recognized.使用 python3 可选closefd
参数被识别。 If set to False
, resulting IO object won't close underlying fd:如果设置为False
,则导致 IO object 不会关闭底层 fd:
if file_path != None:
outputHandle = open(file_path, 'w')
else:
outputHandle = open(sys.stdout.fileno(), 'w', closefd=False)
with outputHandle as handle:
print(my_stuff, file=handle)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.