2010-11-22 1 views
3

여러 TCP 연결이 열려있는 단일 스레드 스크립트에 대화 형 콘솔을 갖고 싶습니다. 이것은 단순히 스레드를 차단하는 표준 입력을 가질 수 없다는 것을 의미합니다.단일 스레드 Python 스크립트에 콘솔 사용

쉬운 방법이 있나요? 아니면 콘솔을 자체 스레드에 넣고 끝내야합니까?

+0

. 내게 당신이 정말로 묘사하고있는 것은 웹 서버 다. 어쨌든 내가 계속 생각하고있는 것이 무엇입니까 –

답변

0

단일 스레드 또는 다중 스레드가 가능하지만 스레드를 사용하지 않을 경우 폴링을 사용해야합니다 (예 : poll (2) 사용). 콘솔 및/또는 TCP 연결은 입력 준비 상태입니다.

+0

그 부분이 있습니다. 콘솔과 같은 방식으로 사용자로부터 입력을 읽는 동시에 편리하게 물건을 출력하는 편리한 방법에 대해 생각하고있었습니다. 마치 라이브러리 나 오픈 소스 애플리케이션에서 이미 수행 된 것처럼, 나는 그것을 볼 수있다. – Blixt

3

당신은 InteractiveConsole (내장에서 '코드'모듈)을 하위 클래스와 기본 InteractiveConsole의 푸시() 메서드에 전달하기 전에있는 StringIO 인스턴스에 표준 출력/표준 에러 리디렉션 래퍼와 푸시() 메소드를 오버라이드 (override) . 래퍼는 2-tuple을 반환 할 수 있습니다. (more, result) 여기서 'more'는 InteractiveConsole이 이 더 많은 입력을 기대하는지 여부를 나타내며 'result'는 InteractiveConsole.push()가 StringIO 인스턴스에 쓴 내용입니다.

소리보다 더 두렵게 들립니다.

import sys 
from cStringIO import StringIO 
from code import InteractiveConsole 
from contextlib import contextmanager 

__all__ = ['Interpreter'] 


@contextmanager 
def std_redirector(stdin=sys.stdin, stdout=sys.stdin, stderr=sys.stderr): 
    """Temporarily redirect stdin/stdout/stderr""" 

    tmp_fds = stdin, stdout, stderr 
    orig_fds = sys.stdin, sys.stdout, sys.stderr 
    sys.stdin, sys.stdout, sys.stderr = tmp_fds 
    yield 
    sys.stdin, sys.stdout, sys.stderr = orig_fds 


class Interpreter(InteractiveConsole): 
    """Remote-friendly InteractiveConsole subclass 

    This class behaves just like InteractiveConsole, except that it 
    returns all output as a string rather than emitting to stdout/stderr 

    """ 
    banner = ("Python %s\n%s\n" % (sys.version, sys.platform) + 
       'Type "help", "copyright", "credits" or "license" ' 
       'for more information.\n') 

    ps1 = getattr(sys, "ps1", ">>> ") 
    ps2 = getattr(sys, "ps2", "... ") 


    def __init__(self, locals=None): 
     InteractiveConsole.__init__(self, locals=locals) 
     self.output = StringIO() 
     self.output = StringIO() 

    def push(self, command): 
     """Return the result of executing `command` 

     This function temporarily redirects stdout/stderr and then simply 
     forwards to the base class's push() method. It returns a 2-tuple 
     (more, result) where `more` is a boolean indicating whether the 
     interpreter expects more input [similar to the base class push()], and 
     `result` is the captured output (if any) from running `command`. 

     """ 
     self.output.reset() 
     self.output.truncate() 
     with std_redirector(stdout=self.output, stderr=self.output): 
      try: 
       more = InteractiveConsole.push(self, command) 
       result = self.output.getvalue() 
      except (SyntaxError, OverflowError): 
       pass 
      return more, result 

체크 아웃이 완료 예를 들어, UDP 소켓의 입력을 받아 들인다 : 여기에 기본 전제이다

시작이 콘솔과 하나 server.py를 실행 다른쪽에있는 client.py. client.py에 보이는 내용은 파이썬의 일반 대화 형 인터프리터와 구별 할 수 없습니다. 모든 명령은 이 평가를 위해 server.py로 라운드 트립 되어도 마찬가지입니다.

물론이 소켓을 사용하는 것은 매우 안전하지 않지만 은 외부 입력을 비동기 적으로 평가하는 방법을 보여줍니다. 은 입력 소스 을 신뢰하는 한 상황에 맞게 조정할 수 있어야합니다. 상황이 '재미'도착할 때 유형 :

while True: continue 

하지만 그건 완전히 다른 문제입니다 ... :-)

필자는 많은 최근에이 질문을 방문하고