代码之家  ›  专栏  ›  技术社区  ›  Blixt

在单线程Python脚本中具有控制台

  •  3
  • Blixt  · 技术社区  · 14 年前

    我想有一个交互式控制台在一个单线程脚本,有几个TCP连接打开。这意味着我不能让一个标准的输入阻塞线程。

    2 回复  |  直到 14 年前
        1
  •  3
  •   evadeflow ekhumoro    14 年前

    用重定向stdout/stderr的包装器重写push()方法 在转发到基服务器之前 (more,result)其中“more”表示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套接字的输入:

    你看到了什么客户端.py应该和python的没有区别 常规交互式解释器,即使所有命令 往返于服务器.py进行评估。

    应该能够适应你的情况,只要你相信 输入源。当有人键入以下内容时,事情变得“有趣”:

    while True: continue
    

    但这完全是另一个问题。。。:-)

        2
  •  0
  •   user502515    14 年前