2011-05-11 65 views
7

我正在尝试编写一些代码将数据放入管道,我希望解决方案是Python 2.6+和3.x兼容。 例子:Python 3写入管道

from __future__ import print_function 

import subprocess 
import sys 

if(sys.version_info > (3,0)): 
    print ("using python3") 
    def raw_input(*prmpt): 
     """in python3, input behaves like raw_input in python2""" 
     return input(*prmpt) 

class pipe(object): 
    def __init__(self,openstr): 
     self.gnuProcess=subprocess.Popen(openstr.split(), 
             stdin=subprocess.PIPE) 

    def putInPipe(self,mystr): 
     print(mystr, file=self.gnuProcess.stdin) 

if(__name__=="__main__"): 
    print("This simple program just echoes what you say (control-d to exit)") 
    p=pipe("cat -") 
    while(True): 
     try: 
      inpt=raw_input() 
     except EOFError: 
      break 
     print('putting in pipe:%s'%inpt) 
     p.putInPipe(inpt) 

上面的代码工作在Python 2.6中,但在Python 3.2失败(请注意,上面的代码大多由2to3的生成 - 我只是搞砸与它一点点,使其蟒蛇2.6兼容)。

Traceback (most recent call last): 
    File "test.py", line 30, in <module> 
    p.putInPipe(inpt) 
    File "test.py", line 18, in putInPipe 
    print(mystr, file=self.gnuProcess.stdin) 
TypeError: 'str' does not support the buffer interface 

我已经试过字节的功能(例如打印(字节(myStr中, 'ASCII'))在这里建议, TypeError: 'str' does not support the buffer interface 但是,这似乎并没有工作。 有什么建议?

+1

试图在同一时间遵守Python 2 *和* 3是非常困难和不必要的。只要写idioamtic,现代(不依赖于在3.x中完全删除的东西)代码和2to3应该工作。如果有一些地方没有,请保留一个补丁,将其更改为3.x兼容并将其应用于2to3的输出。 – delnan 2011-05-11 14:30:43

+0

我明白2to3的意义在于防止用户需要在同一个文件中支持python2和python3。不过,我是这样做的,以说明问题。 2to3转换打印>> self.gnuProcess.stdin,mystr打印(mystr,file = self.gnuProcess.stdin)。但是,转换的输出不起作用(引发TypeError)。我如何编写代码以便(至少)2to3将其转换为功能性的东西? – mgilson 2011-05-11 14:56:50

+0

@delan:更好的是,编写python3代码并用3to2工具翻译它。 – 2014-02-28 13:56:17

回答

7

print函数将其参数转换为字符串表示形式,并将该字符串表示形式输出到给定文件。对于Python 2.x和Python 3.x,字符串表示总是类型str。在Python 3.x中,管道只接受bytes或缓冲区对象,所以这不起作用。 (即使是通过一个bytes对象print,它将被转换成str

一种解决方案是使用write()方法代替(和写入之后冲洗):

self.gnuProcess.stdin.write(bytes(mystr + "\n", "ascii")) 
self.gnuProcess.stdin.flush() 
+0

谢谢,这是有效的 – mgilson 2011-05-11 15:20:12

0

但python2将抱怨

bytes("something", "ascii") 

如果使用可变的bytearray它会在这两个python2和python3不变的工作

self.gnuProcess.stdin.write(bytearray(mystr + "\n", "ascii")) 
self.gnuProcess.stdin.flush()