1

我有以下python代码...

import Tkinter

root = Tkinter.Tk()

root.tk.eval('puts {printed by tcl}')

它将“由 tcl 打印”打印到屏幕上。如何将 tcl 解释器打印到屏幕上的内容捕获到 python 字符串中。

这是我正在做的一个简化示例。我有一个用 python 编写的自动化系统,但是一个由 tcl api 控制的新设备。每个 tcl 命令都会打印“已连接”或“连接失败”之类的内容,我需要能够将这些内容捕获到 python 字符串中,以便自动化系统可以知道发生了什么,例如,如果设备没有连接自动化系统可以重试连接命令。

干杯

从尼克

4

1 回答 1

4

如果您正在运行的代码打印到屏幕上并且您使用 root.tk.eval() 调用它,则您无法捕获它。但是,您可以重新定义“放置”在 tcl 代码中所做的事情,并让它做任何您想做的事情。这是 Tcl 之美的一部分——没有保留字。

只需在 tcl 解释器中创建一个名为“puts”的 proc,但要确保它具有完全相同的接口(即:尊重“-nonewline”,可以写入文件等)。当 puts 正常打印到屏幕上时,您可以让它做任何您想做的事情,例如写入套接字或仅返回它应该打印的字符串。

粗略(未经测试,并使用 -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

这需要一点努力来确保您不会破坏需要标准“puts”语句的 tcl 代码,但这并不难做到。只要确保你有一个参数的特殊情况,“-nonewline”的第一个参数,并且有两个参数(文件描述符和字符串)。

如果您调用 eval 并且它执行两个 puts 语句,或者执行一个 puts 然后执行一些其他代码,它可能会变得复杂,因为 eval 的结果是最后一个语句的结果。但是,您可以通过将 puts 缓冲其输出到全局变量来解决此问题,然后每次执行 eval 时返回该变量的结果。

所以,跳出框框思考一下,你就能找到解决方案。Tcl 非常灵活。

于 2009-11-18T12:41:25.847 回答