python - threading code.InteractiveInterpreter 并在执行命令时获取输出
问题描述
我正在尝试在 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 循环时,我必须等待它出来让我得到结果,而不是单独获取每个打印语句。
caught: 0 main
caught: hi
>>> caught: 0 interpreter
1 main
1 interpreter
2 main
2 interpreter
3 interpreter
4 interpreter
解决方案
@user2357112supportsMonica是正确的。您创建一个线程,然后启动该线程,但该线程没有做任何事情。交互式解释器在线程类中初始化,您向线程类添加了一个函数,但您所做的所有调用都来自主线程并在主线程上运行。
代码在您创建的线程内运行的唯一时间是代码在目标函数中。
我建议您查看 python 文档中的线程,并特别查看如何设置线程的目标以及如何在线程中循环以使其保持活动和工作。然后,您可能还需要考虑Queues
将数据传递给新线程。
推荐阅读
- java - 找不到 org.springframework.boot:spring-boot-test-support:jar:2.2.6.RELEASE
- android - 工具栏中的 SearchView 仅在“搜索模式”下
- c++ - 使用向量进行反向输出,stl
- python - 在 python 中打印时调用多个函数
- r - 使用管道操作数据框
- java - 嵌入式 MongoDb 未用于应用程序测试
- salesforce - 如何在visualforce页面上将多选选项列表呈现为复选框
- java - Get() 方法错误 500,使用 SpringBoot 和 MongoDB 时出现内部服务器错误
- javascript - 类型 'number' 不可分配给类型 'GraphQLScalarType | 不明确的'
- c# - Firebase Realtime Database - Matchmaking using transactions = High download usage