中止对python交互式控制台的评估
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了中止对python交互式控制台的评估,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4103字,纯文字阅读大概需要6分钟。
内容图文
![中止对python交互式控制台的评估](/upload/InfoBanner/zyjiaocheng/667/4bbb164cbe484d1190ae73fe43dfb6c2.jpg)
我正在编写自己的python代码编辑器和终端以取乐,并在现有程序中实现它以增加可写性.
现在,我发现了一个问题,我不知道如何在代码运行后停止评估.那怎么办?
这是我的实现:
import code
import contextlib
import sys
from io import StringIO
import copy
@contextlib.contextmanager
def capture():
oldout,olderr = sys.stdout, sys.stderr
try:
out=[StringIO(), StringIO()]
sys.stdout,sys.stderr = out
yield out
finally:
sys.stdout,sys.stderr = oldout, olderr
out[0] = out[0].getvalue()
out[1] = out[1].getvalue()
class PythonTerminal(code.InteractiveConsole):
def __init__(self, shared_vars):
self.shared_vars_start = copy.deepcopy(shared_vars)
self.shared_vars = shared_vars
super().__init__(shared_vars)
self.out_history = []
def run_code(self,code_string):
with capture() as out:
self.runcode(code_string)
self.out_history.append(out)
return out
def restart_interpreter(self):
self.__init__(self.shared_vars_start)
def stop(self):
raise NotImplementedError
if __name__ == '__main__':
a = range(10)
PyTerm = PythonTerminal({'Betrag': a})
test_code = """
for i in range(10000):
for j in range(1000):
temp = i*j
print('Finished'+str(i))
"""
print('Starting')
t = threading.Thread(target=PyTerm.run_code,args=(test_code,))
t.start()
PyTerm.stop()
t.join()
print(PyTerm.out_history[-1]) # This line should be executed immediately and contain an InterruptError
目的是停止评估,但解释器仍然有效,例如ctrl c.
解决方法:
我认为您无法轻易杀死Python中的线程.但是,您可以杀死一个multiprocessing.Process.因此,您可以使用单独的过程在控制台中执行代码并通过multiprocessing.Queue与之通信.为此,我实现了一个TerminalManager类,该类可以在单独的进程中执行PythonTerminal.run_code并杀死它.请参阅下面的修改后的代码.对此的一个主要缺点是,InteractiveConsole的本地语言在两次调用之间不会保持不变.我添加了一个将本地人存储到搁置文件中的黑客(这可能很糟糕).想到的最快的事情.
import code
import contextlib
import sys
from io import StringIO
import copy
import threading
import multiprocessing
import json
import shelve
class QueueIO:
"""Uses a multiprocessing.Queue object o capture stdout and stderr"""
def __init__(self, q=None):
self.q = multiprocessing.Queue() if q is None else q
def write(self, value):
self.q.put(value)
def writelines(self, values):
self.q.put("\n".join(str(v) for v in values))
def read(self):
return self.q.get()
def readlines(self):
result = ""
while not self.q.empty():
result += self.q.get() + "\n"
@contextlib.contextmanager
def capture2(q: multiprocessing.Queue):
oldout,olderr = sys.stdout, sys.stderr
try:
qio = QueueIO(q)
out=[qio, qio]
sys.stdout,sys.stderr = out
yield out
finally:
sys.stdout,sys.stderr = oldout, olderr
class PythonTerminal(code.InteractiveConsole):
def __init__(self, shared_vars):
self.shared_vars_start = copy.deepcopy(shared_vars)
self.shared_vars = shared_vars
super().__init__(shared_vars)
self.out_history = []
def run_code(self,code_string, q):
# retrieve locals
d = shelve.open(r'd:\temp\shelve.pydb')
for k, v in d.items():
self.locals[k] = v
# execute code
with capture2(q) as out:
self.runcode(code_string)
# store locals
for k, v in self.locals.items():
try:
if k != '__builtins__':
d[k] = v
except TypeError:
pass
d.close()
def restart_interpreter(self):
self.__init__(self.shared_vars_start)
class TerminalManager():
def __init__(self, terminal):
self.terminal = terminal
self.process = None
self.q = multiprocessing.Queue()
def run_code(self, test_code):
self.process = multiprocessing.Process(
target=self.terminal.run_code,args=(test_code, self.q))
self.process.start()
def stop(self):
self.process.terminate()
self.q.put(repr(Exception('User interupted execution.')))
def wait(self):
if self.process.is_alive:
self.process.join()
while not self.q.empty():
print(self.q.get())
if __name__ == '__main__':
import time
a = range(10)
PyTerm = PythonTerminal({'Betrag': a})
test_code = """
import time
a = 'hello'
for i in range(10):
time.sleep(0.2)
print(i)
print('Finished')
"""
mgr = TerminalManager(PyTerm)
print('Starting')
mgr.run_code(test_code)
time.sleep(1)
mgr.stop()
mgr.wait()
test_code = """
import time
_l = locals()
print('a = {}'.format(a))
for i in range(10):
time.sleep(0.1)
print(i)
print('Finished')
"""
print('Starting again')
mgr.run_code(test_code)
mgr.wait()
内容总结
以上是互联网集市为您收集整理的中止对python交互式控制台的评估全部内容,希望文章能够帮你解决中止对python交互式控制台的评估所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。