【问题标题】:threading code.InteractiveInterpreter and getting output as commands are executedthreading code.InteractiveInterpreter 并在执行命令时获取输出
【发布时间】:2021-06-04 01:12:52
【问题描述】:

我正在尝试在 GUI pyqt5 中创建控制台,但无法从 InteractiveInterpreter 获取输出。我不知道我的 InteractiveInterpreter 的线程是否正确。当我运行下面的代码(不尝试捕获输出)时,代码是按顺序打印的,但我希望输出是这样的:

hi
0 interpreter
0 main
1 interpreter
1 main
2 interpreter
2 main
3 interpreter
4 interpreter

相反,我得到了这个:

hi
0 interpreter
1 interpreter
2 interpreter
3 interpreter
4 interpreter
0 main
1 main
2 main

代码:

import code
import threading
from time import sleep 
import sys
    

class IC(threading.Thread):
    def __init__(self, context=None):
      threading.Thread.__init__(self)
      
      self.Console = code.InteractiveInterpreter(context)

    def push(self, x, sym=''):
        return self.Console.runsource(x,sym)



if __name__ == "__main__":
    a=IC()
    a.start()
    a.push("print('hi')")
    a.push("from time import sleep")
    a.push("for i in range(5):\n\t print(i,'interpreter')\n\t sleep(1)\n")

    for i in range(3):
        print(i, 'main')
        sleep(1)

更新: 我的代码现在像我预期的那样运行,但是我无法捕获打印语句。我尝试使用 contxtlib,但我得到的是正在打印的文本,但是在一个大块中。如何在打印语句出现时捕获它们,稍后我会将这些字符串传递给 qtextedit。

这是我现在使用的代码:

import code
import threading, queue
from time import sleep 
import sys

import io
from contextlib import redirect_stdout


class IC:
    def __init__(self):
        self.On = True
        self.qin = queue.Queue()
        self.qout = queue.Queue()
        self.thread = threading.Thread(target=self.runtime, daemon=True).start()

    def push(self, x):
        self.qin.put(x)

    def runtime(self):
        self.Console = code.InteractiveInterpreter()
        while self.On:
            f = io.StringIO()
            with redirect_stdout(f):
                if self.qin.qsize()>0:
                    self.Console.runsource(self.qin.get())
            if f.getvalue():
                print("caught:", f.getvalue())


if __name__ == "__main__":
    a=IC()
    a.push("print('hi')")
    a.push("from time import sleep")
    a.push("for i in range(5):\n\t print(i,'interpreter')\n\t sleep(2)\n")

    for i in range(3):
        print(i, 'main')
        sleep(1.5)

这是我得到的输出,处于空闲状态。前两行是我想要/期望的,但是当我进入 for 循环时,我必须等待它出来让我得到结果,而不是单独获取每个 print 语句。

caught: 0 main

caught: hi

>>> caught: 0 interpreter
1 main
1 interpreter
2 main
2 interpreter
3 interpreter
4 interpreter

【问题讨论】:

  • 你实际上并没有在线程中做任何事情。
  • 请避免不必要的(和错误的)代码 sn-p 标签。还尝试使您的代码尽可能少,避免重复对您的问题并不重要的代码和函数或 cmets,正如已经指出的那样,它缺少问题的一个重要部分:您使用线程的目的是什么,因为现在它什么也没做:提供一个 both minimal and reproducible. 的例子
  • @musicamante,对不起,我添加了与我的问题有关的标签。我也删除了附加代码
  • @user169808 with "tags" 我的意思是 HTML 标签 (<!-- begin snippet: ... -->),不幸的是,在另一个用户正确删除它们后,您刚刚恢复了这些标签。阅读有关formatting code 的更多信息,并记住“语言”标签必须反映使用的实际语言(在您的情况下,python,而不是 html)。

标签: python python-3.x pyqt5


【解决方案1】:

@user2357112supportsMonica 是正确的。您创建一个线程,然后启动该线程,但该线程没有做任何事情。交互式解释器在线程类中初始化,您向线程类添加了一个函数,但您所做的所有调用都来自主线程并在主线程上运行。

代码在您创建的线程内运行的唯一时间是代码在目标函数中。

我建议您查看 python 文档中的线程,并特别查看如何设置线程的目标以及如何在线程中循环以使其保持活动和工作。然后您可能还需要查看 Queues 以将数据传递给新线程。

【讨论】:

  • 感谢我重写了课程,现在这部分工作就像我期望的那样
  • 希望我能提供帮助。如果我的回答确实有帮助,请将其标记为已接受的答案,以便可以关闭此问题。
猜你喜欢
  • 2019-11-29
  • 2014-06-29
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 2014-06-24
  • 2021-03-27
  • 2013-07-30
相关资源
最近更新 更多