有没有办法实时编程Python curses应用程序?
有没有办法创建一个第二个终端,这样所有调用 curses
函数的操作都在这个新终端上进行,而不是在现有的终端里?我发现当我可以互动地尝试东西时,工作效率更高,所以我希望能在一个终端里运行一个互动的 Python 解释器,而在另一个终端里看到 curses 的输出。
目前的情况是,在一个互动窗口中调用 initscr()
要么失败(在 PyDev 中),要么会永久性地让主窗口无法刷新(在 Spyder 中),或者在控制台中造成奇怪的行为(在 IPython 中)。
有没有可能使用 setupterm()
来控制一个不同的终端?如果可以的话,我该从哪里获取一个不同的 TERM
字符串来调用它呢?
3 个回答
嗯,我不太确定我完全理解你想做什么。不过我明白的是,你想要一个标准的Python控制台,在那里你可以动态输入代码。但是当你调用一个函数时,这个函数处理的结果会显示在另一个终端上,对吗?
为了实现这个功能,我觉得可以用“客户端-服务器”的架构。
因为一个进程有标准输出(stdout)和标准错误(stderr),在多进程的架构中,你可以把标准错误当作函数的输出通道。但是问题在于如何初始化一个与主终端分开的另一个终端。(不能在同一个空间里重叠)
如果你的主程序启动一个服务器(在另一个Python进程中,因为服务器本身的特性),然后把输出发送给所有连接到它的客户端。这样你就可以在多个终端客户端和/或其他能够连接到你服务器的电脑上看到函数的输出。
在我看来,这比尝试使用'curses'包要简单得多。不过如果你唯一的目的是想了解你的代码,我觉得这样做有点复杂(没有额外的价值)。
你仍然可以选择把函数的输出写入一个文本文件(log.txt)。
你可以使用 code.InteractiveConsole 和 SocketServer,把一个 Python 交互式命令行连接到一个网络端口,这样就可以通过这个端口进行开发。下面是一个简单的例子:
import sys
import SocketServer
from code import InteractiveConsole
class InteractiveServer(SocketServer.BaseRequestHandler):
def handle(self):
file = self.request.makefile(mode='rw')
shell = Shell(file)
try:
shell.interact()
except SystemExit:
pass
class Shell(InteractiveConsole):
def __init__(self, file):
self.file = sys.stdout = file
InteractiveConsole.__init__(self)
return
def write(self, data):
self.file.write(data)
self.file.flush()
def raw_input(self, prompt=""):
self.write(prompt)
return self.file.readline()
if __name__ == '__main__':
HOST, PORT = "127.0.0.1", 9999
server = SocketServer.TCPServer((HOST, PORT), InteractiveServer)
server.serve_forever()
当你把这个设置好后,就可以从另一个终端连接到 9999 端口,开始你的操作。你可以在 这个截图 (PNG) 中看到它是如何工作的。
关于如何使用 InteractiveConsole 的基本知识,可以参考 这篇文章。我对它进行了修改,使其可以与 SocketServer 一起使用,以便于我正在进行的另一个项目。
我觉得不太可能,因为curses模块主要是用C语言实现的,可能没有提供这样的接口。不过如果你对这个语言比较熟悉,看看源代码也许会有帮助。
不过在读到你的问题时,我想到了另一种我在其他场合使用的技巧。你可以通过另一个终端或编辑器保存一个脚本,然后用类似于dnotify命令(或者简单的轮询)的方法,把它加载到你正在运行的程序里。
还有一个想法是使用套接字来发送命令并执行它们。当然,这在安全方面是有风险的,所以一定要采取必要的防护措施。
你需要建立一些基础设施,但这可能比给curses添加多个设备支持要简单得多。