【问题标题】:using Python 'with' statement with sys.stdout在 sys.stdout 中使用 Python 'with' 语句
【发布时间】:2014-04-11 10:49:38
【问题描述】:

我总是使用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

【问题讨论】:

    标签: python stream stdout with-statement


    【解决方案1】:

    问题是,您不需要将上下文处理器与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】:

      您可以创建一个上下文管理器并像这样使用它

      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"
      

      如果您不向file_writer 传递任何输入,它将使用sys.stdout

      【讨论】:

      • 我会将!= 替换为is not
      • @Blender 我正在考虑交换 ifelse 部分并简单地做 if file_name :) 无论如何,用 is not 修复它:)
      • 这值得更多的支持!它为我提供了一个很好的开始,上下文管理器的方法是不突兀的
      • 我认为应该是writer = open(file_name, "w") 而不是writer = open("Output.txt", "w"),但是很好的答案!
      【解决方案3】:

      最简单的方法是简单地使用“老派”流文件名,这样您的代码就不必更改。在 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 中测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        相关资源
        最近更新 更多