2010-11-22 20 views
3

Birden çok TCP bağlantısının açık olduğu tek iş parçacıklı bir komut dosyasında etkileşimli bir konsola sahip olmak isterim. Bu, yalnızca iş parçacığını engelleyen standart bir giriş yapamıyorum anlamına gelir.Tek iş parçacıklı bir Python komut dosyasında bir konsolun bulunması

Bunu yapmanın kolay bir yolu var mı? Ya da konsolu sadece kendi ipliğine koyup onunla mı yapmalıyım?

+0

. Bana anlattığın şey, bir web sunucusudur. Şu an ne düşündüğümü aklımda –

cevap

0

Tek iş parçacıklı veya çok iş parçacıklı yapar, ancak iş parçacığı kullanmamayı seçerseniz, yoklama kullanmanız gerekir (bu C örneğinde anket (2) kullanılarak yapılabilir, örneğin). konsol ve/veya TCP bağlantılarının girişi hazırdır.

+0

Evet var. Kullanıcıdan gelenleri konsol benzeri bir şekilde okurken ve aynı zamanda malzeme çıkarırken de uygun yollar bulmayı düşünüyordum. Bir kütüphanede veya açık kaynak uygulamada zaten yapıldıysa, ona bakabilirim. – Blixt

3

için InteractiveConsole (yerleşiği den 'kod' modülü) alt sınıf ve taban InteractiveConsole push() yöntemine yönlendirmeden önce bir StringIO örneğine stdout'u/Stderr yönlendiren bir sargı ile itme() yöntemini geçersiz . Sarıcınız 2-tuple (daha fazla, sonuç) 'daha fazla', 'daha fazla', InteractiveConsole'un daha fazla girdi bekleyip beklemediğini ve 'result', InteractiveConsole.push() 'ın StringIO örneğiniz için yazıp yazılmadığını gösterir.

Bundan daha sert geliyor.

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 

Kontrol dışarı bu tam bir örnek, UDP soket girişini kabul eder:: İşte temel dayanak noktası

Başlat iki konsolları ve birinde server.py çalıştırın client.py diğerinde. Tüm komutlar değerlendirme için server.py'ye dönüşlü olsa bile, client.py'de gördüğünüz python'un düzenli etkileşimli yorumlayıcısından ayırt edilemez.

Elbette, bu gibi yuvalar kullanmak güvensizdir, ancak , harici girişin senkronize olmayan şekilde nasıl değerlendirileceğini gösterir. , giriş kaynağına güvendiğiniz sürece durumunuza uyarlanabilmeniz gerekir. Yapılacaklar 'ilginç' olsun birileri türleri:

while True: continue 

Ama bu tamamen başka bir sorun var ... :-)

Ive çok yakın zamanda bu soruyu ziyaret
İlgili konular