2011-05-11 4 views
7

파이프에 데이터를 넣기위한 코드를 작성하려고합니다. 파이썬 2.6+ 및 3.x와 호환되도록 솔루션을 원합니다. 예 :파이썬 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) 

위의 코드는 파이썬 2.6에서 작동하지만 파이썬 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, '아스키')) 여기에 제안, TypeError: 'str' does not support the buffer interface 을 시도했다 그러나 그것은 작동하지 않습니다. 어떤 제안?

+1

동시에 Python 2 *와 * 3을 따르려고하면 ** 매우 어렵고 불필요합니다. idioamtic, modern (3.x에서 완전히 제거 된 항목에 의존하지 않음) 코드를 작성하면 2to3이 작동합니다. 그렇지 않은 곳이 몇 군데 있다면 패치를 3.x와 호환되도록 변경하고 2to3의 출력에 적용하십시오. – delnan

+0

2to3의 요점은 사용자가 python2와 python3을 동일한 파일에서 지원할 필요가 없다는 것을 이해합니다. 그러나, 나는 그 문제를 설명하기 위해 위에했다. 2to3 변환 print >> self.gnuProcess.stdin, 인쇄 할 mystr (mystr, file = self.gnuProcess.stdin). 그러나 변환 된 출력이 작동하지 않습니다 (TypeError가 발생 함). 어떻게 코드를 작성하여 (최소한) 2to3이 기능적으로 변환 할 수 있도록할까요? – mgilson

+0

@delan : 더 나은 것은 python3 코드를 작성하고 3to2 도구로 다시 번역하는 것입니다. –

답변

7

print 함수는 인수를 문자열 표현으로 변환하고이 문자열 표현을 주어진 파일로 출력합니다. 문자열 표현은 항상 Python 2.x 및 Python 3.x 모두에 대해 str 유형입니다. Python 3.x에서 파이프는 bytes 또는 버퍼 객체 만 허용하므로이 기능은 작동하지 않습니다.

해결책 대신 write() 방법을 사용하는 것입니다 (. 당신이 printbytes 개체를 전달하더라도, str로 변환됩니다) (쓰기 후 플러싱) :

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

고마워, 그 작품 – mgilson

0

을하지만 python2 것 이 python2하고 변경되지 않은 python3 모두에서 작동합니다 BYTEARRAY 당신이 변경할 수를 사용하는 경우

bytes("something", "ascii") 

에 대해 불평

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