2011-05-11 106 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()