【问题标题】:get global tcl array in python or c++在 python 或 c++ 中获取全局 tcl 数组
【发布时间】:2013-11-27 22:34:09
【问题描述】:

我需要从 tcl 文件(保存在 tcl 中的变量)中导入现有信息,但我对 tcl 完全不熟悉。我需要一个简单的解决方案(简短),它不需要超级健壮。 我有一个定义全局的 tcl 文件。这是一个小sn-p:

test.tcl:

global gP
set gP(1,1) {-2.77577 -2.66083 14.6978}
set gP(1,2) {-2.2751 -1.91189 13.5285}
set gP(1,3) {-1.46855 -1.21695 11.8953}
...
set gP(1,spline) [list \
  {p (-0.005623,0.225326,4.821360) t (-0.155507,0.806054,-0.571047) tx (0.000000,0.578079,0.815981)} \{p (-0.006889,0.231865,4.816766) t (-0.156976,0.809595,-0.565609) tx (0.000000,0.572709,0.819758)} \
...
  {p (2.224570,6.136620,-6.119510) t (0.901583,0.422393,0.093441) tx (0.000000,0.215995,-0.976394)} \
  ]
...
set gP(1,4) {-0.673205 -0.728409 10.3576}
set gP(1,5) {-0.261822 -0.476418 9.47673}
set gP(1,name) {path1}
...

我想做的是从 python 或 c++ 运行 tcl 以生成该语言的 gP。所以像(在python中:)

from Tkinter import Tcl
MYFILE = 'test.tcl'
tcl = Tcl()
gP = tcl.evalfile(MYFILE)

我的最终目标是将它融入 c++,但我不需要所有 gP。到目前为止,我遇到的一个问题是 gP 是一个数组,因此在 Tkinter 中不会以正常方式返回。

这不需要很优雅,我只会使用一次或两次。我愿意在 python 中操作变量,在文本(或 CSV)文件中打印出我需要的内容,然后将其读入 c++ 以填充变量。

编辑

按照 patthoyts 描述的方式进行操作是一个非常好的开始!我想我需要一个(或两个级别的解析?

我已经这样做了(gPathPoints 和 gP 是相同的,只是不同的 varname):

a  = eval(tcl.eval('''set r {};
  foreach k [array names gPathPoints] {
    lappend r "'$k': '$gPathPoints($k)'"
  };
  set r "{[join $r ,]}"
  '''))

Python 吐出了一本不错的字典,但键有点古怪:

'100,0': '-2.939 -3.02 15.136',
'100,1': '-2.77577 -2.66083 14.6978',
'100,10': '-0.00681104 0.408274 3.53018',
...

我可能可以用一个简单的 c++ 方法来解决这个问题,但我认为在 tcl 中以下会更容易:

'100,spline': '{p (-2.939000,-3.020000,15.136000) t (0.242924,0.657821,-0.712923) tx (0.000000,0.734938,0.678134)} {p (-2.934674,-3.008616,15.123467) t (0.250593,0.647200,-0.719955) tx (0.000000,0.743684,0.668531)}

【问题讨论】:

  • 有很多方法可以做到这一点,一个简单的方法是在脚本运行后array get gP(Tkinter 在某处有一个 eval 函数)。结果是一个列表,其中奇数元素是键,偶数元素是前一个键的值。

标签: c++ python tcl


【解决方案1】:

使用python:

from Tkinter import *
# create an array in tcl
tk.eval('array set a {a 1 b 2 c 3 d "4 5 6"}')
s = tk.eval('array get a')

这会将数组作为字符串返回,但使用 tcl 列表格式:'d {4 5 6} a 1 b 2 c 3',因此您需要重新解析一下。您可以通过在 Tcl 中轻松地进行解析来将其转换为 python dict:

a  = eval(tk.eval('''set r {};
  foreach k [array names a] {
    lappend r "'$k': '$a($k)'"
  };
  set r "{[join $r ,]}"
  '''))

使用上面的示例代码会产生:

>>> a
{'a': '1', 'c': '3', 'b': '2', 'd': '4 5 6'}
>>> a['d']
'4 5 6'
>>>

如果数组值嵌入了引号,那么您必须更加小心引用处理,但这也足够简单。

在 C++ 中,我认为您不妨评估 array get $varname 以获得 Tcl 列表对象。然后您可以使用Tcl_ListObjGetElements 和相关函数遍历键值对列表。

【讨论】:

  • 我还要指出 Tcl_GetVar2Ex 函数用于读取数组的单个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多