从 Python 运行 TCL 代码(在现有的 TCL shell 上) [英] Running TCL code (on an existing TCL shell) from Python

查看:47
本文介绍了从 Python 运行 TCL 代码(在现有的 TCL shell 上)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简介

我最近开始在 Linux 下开发一个遗留产品,它包含一个内置的 TCL shell.由于公司限制,我无法控制幕后",我可以编写的所有代码都必须在此 TCL shell 下运行,处理产品预定义的笨拙的 TCL API.

I recently started working on a legacy product, under Linux, which incorporates a builtin TCL shell. Due to company limitations, I can't gain control to "behind the scenes" and all of the code I can write must be run under this TCL shell, handling the pre-defined clumsy TCL API of the product.

我发现自己有几次想知道是否可以将一些 Python 修补到此设置中,因为某些解决方案在 Python 中似乎比在 TCL 中更合理.通过修补 Python,我的意思是:从 TCL 代码本身调用 Python 代码(例如,这可以通过 Elmer 完成),或者从产品外部使用 Python 来包装 TCL API(我没有找到经典"解决方案).

I found myself wondering a few times whether it will be possible to patch some Python into this setup, as some solutions seem more legitimate in Python than in TCL. By patching Python I mean: either calling the Python code from the TCL code itself (which can be done with Elmer, for example), or to use Python from outside of the product to wrap the TCL API (for which I found no "classic" solution).

问题

鉴于该产品已经一个现有的 TCL shell其中,我浏览过的大多数解决方案(例如 Tkinter)都不能用于从 Python 运行 TCL 代码.我需要将代码注入"到现有的 shell.

Given that the product already has an existing TCL shell in it, most solutions I browsed through (e.g. Tkinter) can't be used to run the TCL code from Python. I need to "inject" the code to the existing shell.

考虑的解决方案

作为一个解决方案,我考虑在 TCL 端建立一个简单的服务器,它运行从 Python 端接收到的简单命令.我写了一个小演示,它奏效了.这使我能够用 Python 为笨拙的 TCL API 编写一个漂亮的、基于类的包装器,还可以管理命令队列等.

As a solution, I thought about bringing up a simple server on the TCL side which runs simple commands it receives from the Python side. I wrote a small demo and it worked. This enabled me to write a nice, class based, wrapper in Python for the clumsy TCL API, also manage a command queue, etc.

我想到的另外两个解决方案是从 Python 分叉软件并使用读/写文件描述符或通过 FIFO 而不是套接字连接.

Another two solutions I thought of is forking the software from Python and playing with the read/write file descriptors or connecting through FIFO rather than a socket.

但是,我想知道我是否真的做对了,或者你能提出更好的解决方案吗?

However, I wondered whether I'm actually doing it right or can you suggest a better solution?

提前致谢.

推荐答案

首先:如果你只是想要一个基于类的 OO 系统来编写你的代码,你不需要 python,Tcl 可以很好地做 OO.(内置于 8.6,但在旧版本中也有很多选项可以获取 OO 功能、类等,例如 Tcllibs SNITSTOOOP

First: If you just want a class based OO system to write your code in, you don't need python, Tcl can do OO just fine. (built in with 8.6, but there are quite a few options to get OO features, classes etc. in older versions too, e.g. Tcllibs SNIT or STOOOP

如果您仍然觉得 Python 是手头任务的高级工具(例如,由于对某些任务有更好的库支持),您可以使用 Tcllib comm 包远程控制"Tcl 解释器.这需要您想要控制的 Tcl shell 中的工作事件循环,否则它很容易做到.

If you still feel Python is the superior tool for the task at hand (e.g. due to better library support for some tasks), you can 'remote control' the Tcl interpreter using the Tcllib comm package. This needs a working event loop in the Tcl shell you want to control, but otherwise it is pretty simple to do.

在你的 Tcl shell 中,安装 Tcllib comm 包.(如果您需要帮助,请再次询问)

In your Tcl shell, install the Tcllib comm package. (ask again if you need help with that)

完成后,在 Tcl shell 中启动通信服务器.

Once you have that, start the comm server in your Tcl shell.

package require comm
set id [::comm::comm self]
# write ID to a file
set fd [open idfile.txt w]
puts $fd $id
close $fd
proc stop_server {} {set ::forever 1 }
# enter the event loop
vwait forever

在 python 方面,你几乎可以做同样的事情,只是在 Tkinter 代码中.

On the python side, you do nearly the same, just in Tkinter code.

基本上是这样的:

import Tkinter
interp = Tkinter.Tcl()
interp.eval('package require comm')

# load the id
with open('idfile.txt') as fd:
    comm_id = fd.read().strip()

result = interp.eval(
    'comm::comm send {0!s} {1!s}'.format(comm_id, '{puts "Hello World"}')

使用 python 代码和你的 shell,你应该看到 Hello World 打印在你的 shell 中.

Using that python code and your shell, you should see Hello World printed in your shell.

阅读通信手册了解更多细节,如何保护事物,获取回调等.comm

Read the comm manual for more details, how to secure things, get callbacks etc. comm

如果您不喜欢 tkinter 的负担,您也可以为 comm 实现有线协议,在 Twisted 或 Python 3.x 中新的异步支持中应该不会太难.在线协议记录在:通信线路协议

If you don't like the tkinter burden, you can implement the wire procotol for comm too, should not be too hard in Twisted or with the new async support in Python 3.x. The on the wire protocol is documented in: comm wire protocol

这篇关于从 Python 运行 TCL 代码(在现有的 TCL shell 上)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆