首页 > 解决方案 > 在 Python 中解析从 TCL 返回的关联数组

问题描述

我有一个从 Python 调用 TCL 脚本的要求。我的要求是从 python 调用 TCL proc。TCL proc 将结果作为数组返回。我需要在 Python 中解析返回的数组以形成字典。下面是一个工作代码。有没有更有效的方法来做同样的事情?

Python代码

import tkinter
import shlex

r=tkinter.Tk()
r.tk.eval('source proc.tcl')
arr = []
arr = r.tk.eval('processarray arr')
print(arr)
j=0
for i in arr.split(' '):
    print(i)
d = {}
ssplit = arr.split()
print(len(ssplit))
print(len(ssplit)/2)
j=int(len(ssplit)/2)
k=0
for i in range (j):
    key = ssplit[k]
    d[key] = ssplit[k+1]
    k += 2
print(d)

TCL代码

proc processarray { $arr } {
    array set arr " arrlist 25645"
    set arr(0) "11"
    set arr(1) "10"
    set arr(2) "20"
    set arr(3) "30"
    set arr(4) "40"
    return [array get arr]
}

预期结果

{'4': '40', '0': '11', '1': '10', 'arrlist': '25645', '2': '20', '3': '30'}

标签: pythondictionarytclassociative-array

解决方案


Python 的 Tkinter 包没有很好地记录,所以我不得不深入研究它的源代码......

有一个_splitdict()函数,给定一个包含偶数个 tcl 单词的字符串,就像 Tcl'sarray get返回的那样,将它作为 python 字典返回。我不太了解 Python,但我敢打赌,下划线和笨拙的界面意味着它是内部的,你不应该使用它。但似乎没有公开的替代方案:

>>> import tkinter
>>> tcl = tkinter.Tcl()
>>> tkinter._splitdict(tcl, 'foo 1 bar 2 baz {3 4}')
{'bar': '2', 'foo': '1', 'baz': '3 4'}

或者,您可能只编写在内部执行其功能的函数。重要的是tk.splitlist('some string'),它根据 tcl 规则将其参数分解为单词 - 需要正确处理array get返回的列表的单个单词中的空格或类似的东西(参见上面的示例)。

A(未经测试),精简版。原文可以在 Python 源码中找到

def splitdict(v):
    """Return a properly formatted dict built from Tcl list pairs.
    Tcl list is expected to contain an even number of elements.
    """
    t = r.tk.splitlist(v)
    if len(t) % 2:
        raise RuntimeError('Tcl list representing a dict is expected '
                           'to contain an even number of elements')
    it = iter(t)
    dict = {}
    for key, value in zip(it, it):
        key = str(key)
        dict[key] = value
    return dict

推荐阅读