我总是使用with
语句打开并写入文件:
with open('file_path', 'w') as handle:
print >>handle, my_stuff
但是,有一个实例我需要能够更灵活,并写入sys.stdout
(或其他类型的流),如果提供而不是文件路径:
所以,我的问题是:有没有办法将with
语句与真实文件和sys.stdout
一起使用?
请注意,我可以使用以下代码,但我认为这违背了使用with
的目的:
if file_path != None:
outputHandle = open(file_path, 'w')
else:
outputHandle = sys.stdout
with outputHandle as handle:
print >>handle, my_stuff
答案 0 :(得分:7)
您可以创建一个上下文管理器并像这样使用它
import contextlib, sys
@contextlib.contextmanager
def file_writer(file_name = None):
# Create writer object based on file_name
writer = open("Output.txt", "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"
如果您未将任何输入传递给file_writer
,则会使用sys.stdout
。
答案 1 :(得分:2)
事情是,您不需要使用带有stdout
的上下文处理器,因为您没有打开或关闭它。一种不那么花哨的抽象方式是:
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()
答案 2 :(得分:0)
最简单的方法是简单地使用“旧学校”流式文件名,这样您的代码就不必更改。在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)
此代码在Python 2.7.3和3.3.5中进行了测试