我有以下 python 代码...
import Tkinter
root = Tkinter.Tk()
root.tk.eval('puts {printed by tcl}')
Run Code Online (Sandbox Code Playgroud)
它会在屏幕上打印“printed by tcl”。如何将 tcl 解释器打印到屏幕上的内容捕获到 python 字符串中。
这是我正在做的事情的简化示例。我有一个用 python 编写的自动化系统,但有一个由 tcl api 控制的新设备。每个 tcl 命令都会打印“已连接”或“连接失败”之类的内容,我需要能够将这些内容捕获到 python 字符串中,以便自动化系统可以知道发生了什么,例如,如果设备未连接自动化系统可以重试连接命令。
干杯
来自尼克
如果您正在运行的代码打印到屏幕上并且您使用 root.tk.eval() 调用它,则您无法捕获该代码。但是,您可以在 tcl 代码中重新定义“puts”的作用,并让它执行您想要的任何操作。这是 Tcl 之美的一部分——没有保留字。
只需在 tcl 解释器中创建一个名为“puts”的过程,但要确保它具有完全相同的接口(即:尊重“-nonewline”,可以写入文件等)。当 put 通常打印到屏幕上时,您可以让它执行您想要的任何操作,例如写入套接字或仅返回它应该打印的字符串。
粗略地(未经测试,并忽略带有 -nonewline 的情况):
root.tk.eval('''
rename puts original_puts
proc puts {args} {
if {[llength $args] == 1} {
return "=> [lindex $args 0]"
} else {
eval original_puts $args
}
}
''')
foo = root.tk.eval('puts "hello, world"')
print foo
=> hello, world
Run Code Online (Sandbox Code Playgroud)
这需要一点努力来确保您不会破坏需要标准“puts”语句的 tcl 代码,但这并不难做到。只需确保一个参数有特殊情况,即“-nonewline”的第一个参数,以及有两个参数(文件描述符和字符串)的情况。
如果您调用 eval 并且它执行两个 put 语句,或者执行一个 put 然后执行一些其他代码,则情况可能会变得复杂,因为 eval 的结果是最后一个语句的结果。但是,您可以通过将其输出缓冲到全局变量中来解决这个问题,然后在每次执行 eval 时返回该变量的结果。
因此,跳出框框思考一下,你就能找到解决方案。Tcl非常灵活。