代码之家  ›  专栏  ›  技术社区  ›  l0b0

Pythonic等价于./foo.py<bar.png

  •  1
  • l0b0  · 技术社区  · 14 年前

    我有一个Python程序 sys.stdin ,所以我可以用 ./foo.py < bar.png ./test.py < test.png . 我想我用不了 fileinput Image.open(sys.stdin) PIL .

    4 回复  |  直到 14 年前
        1
  •  3
  •   Richard Fearn    14 年前

    您应该对脚本进行泛化,以便除了用作独立程序之外,还可以从测试脚本调用它。下面是一个执行此操作的示例脚本:

    #! /usr/bin/python
    
    import sys
    
    def read_input_from(file):
        print file.read(),
    
    if __name__ == "__main__":
        if len(sys.argv) > 1:
            # filename supplied, so read input from that
            filename = sys.argv[1]
            file = open(filename)
        else:
            # no filename supplied, so read from stdin
            file = sys.stdin
        read_input_from(file)
    

    如果使用文件名调用此文件,则将显示该文件的内容。否则,将显示从stdin读取的输入。(能够在命令行上传递文件名对于 foo.py 脚本。)

    在测试脚本中,现在可以调用 食品

    #! /usr/bin/python
    
    import foo
    
    file = open("testfile", "rb")
    foo.read_input_from(file)
    
        2
  •  2
  •   orip    14 年前
    • 函数或类应该接受流,而不是选择使用哪个流。
    • 你的 main 函数将选择 sys.stdin .
    • StringIO 实例或测试文件。

    # foo.py
    import sys
    from PIL import Image
    
    def foo(stream):
      im = Image.open(stream)
      # ...
    
    def main():
      foo(sys.stdin)
    
    if __name__ == "__main__":
      main()
    

    测试:

    # test.py
    import StringIO, unittest
    import foo
    
    class FooTest(unittest.TestCase):
      def test_foo(self):
    
        input_data = "...."
        input_stream = StringIO.StringIO(input_data)
        # can use a test file instead:
        # input_stream = open("test_file", "rb")
    
        result = foo.foo(input_stream)
        # asserts on result
    
    if __name__ == "__main__":
      unittest.main()
    
        3
  •  1
  •   l0b0    14 年前

    一个 comp.lang.python post 说明了方法:用StringIO()对象替换sys.stdout,然后用 getvalue()

    def setUp(self):
        """Set stdin and stdout."""
        self.stdin_backup = sys.stdin
    
        self.stdout_backup = sys.stdout
        self.output_stream = StringIO()
        sys.stdout = self.output_stream
    
        self.output_file = None
    
    
    def test_standard_file(self):
        sys.stdin = open(EXAMPLE_PATH)
        foo.main()
        self.assertNotEqual(
            self.output_stream.getvalue(),
            '')
    
    
    def tearDown(self):
        """Restore stdin and stdout."""
        sys.stdin = self.stdin_backup
        sys.stdout = self.stdout_backup
    
        4
  •  0
  •   petraszd    14 年前

    你总是可以给你的 stdin

    import sys
    import StringIO
    
    mockin = StringIO.StringIO()
    mockin.write("foo")
    mockin.flush()
    mockin.seek(0)
    
    setattr(sys, 'stdin', mockin)
    
    def read_stdin():
        f = sys.stdin
        result = f.read()
        f.close()
        return result
    
    print read_stdin()
    

    另外,不要忘记恢复 当你取消考试的时候。