使用TKinter通过[clock format]更改proc返回的方式

2024-06-23 03:30:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用TKinter从Python访问现有的Tcl库。其中一个Tcl进程在列表中查找值,如果找不到值,则返回“”。Python代码将返回值视为unicode,并检查它是否等于“”。在Tcl代码中调用[clock format]之前,这种方法工作得非常好。之后,Python代码将返回值视为元组。我可以在Python代码中添加一些额外的逻辑来处理这个问题,但是似乎有一些更大的问题正在发生,可能会产生其他的影响。你知道吗

Python程序示例:

import Tkinter

_tclsh = Tkinter.Tcl()

_tclsh.eval('proc returnBlank { } { return "" }')
_tclsh.eval('proc returnNotBlank { } { return "not blank" }')

print "Before calling clock"
_tclsh.eval('set shouldBeBlank [returnBlank]')
shouldBeBlank = _tclsh.getvar('shouldBeBlank')
print "shouldBeBlank is ", shouldBeBlank, " with type ", type(shouldBeBlank)

_tclsh.eval('set shouldNotBeBlank [returnNotBlank]')
shouldNotBeBlank = _tclsh.getvar('shouldNotBeBlank')
print "shouldNotBeBlank is ", shouldNotBeBlank, " with type ", type(shouldNotBeBlank)

print "\nCalling [clock seconds]"
_tclsh.eval('puts [clock seconds]')
_tclsh.eval('set shouldBeBlank [returnBlank]')
shouldBeBlank = _tclsh.getvar('shouldBeBlank')
print "shouldBeBlank is ", shouldBeBlank, " with type ", type(shouldBeBlank)

_tclsh.eval('set shouldNotBeBlank [returnNotBlank]')
shouldNotBeBlank = _tclsh.getvar('shouldNotBeBlank')
print "shouldNotBeBlank is ", shouldNotBeBlank, " with type ", type(shouldNotBeBlank)

print "\nCalling [clock format [clock seconds]]"
_tclsh.eval('puts [clock format [clock seconds]]')
_tclsh.eval('set shouldBeBlank [returnBlank]')
shouldBeBlank = _tclsh.getvar('shouldBeBlank')
print "shouldBeBlank is ", shouldBeBlank, " with type ", type(shouldBeBlank)

_tclsh.eval('set shouldNotBeBlank [returnNotBlank]')
shouldNotBeBlank = _tclsh.getvar('shouldNotBeBlank')
print "shouldNotBeBlank is ", shouldNotBeBlank, " with type ", type(shouldNotBeBlank)

结果输出为:

Before calling clock
shouldBeBlank is    with type  <type 'unicode'>
shouldNotBeBlank is  not blank  with type  <type 'str'>

Calling [clock seconds]
1431623835
shouldBeBlank is    with type  <type 'unicode'>
shouldNotBeBlank is  not blank  with type  <type 'str'>

Calling [clock format [clock seconds]]
Thu May 14 13:17:15 EDT 2015
shouldBeBlank is  ()  with type  <type 'tuple'>
shouldNotBeBlank is  not blank  with type  <type 'str'>

如您所见,只有空字符串受到影响,调用[clock]不会引起问题;只有[clock format]。你知道吗

任何帮助都将不胜感激。你知道吗

注意:我尝试了不同的方法返回空字符串,但它们不影响输出。我试过:

_tclsh.eval('proc returnBlank { } { return }')
_tclsh.eval('proc returnBlank { } { return {} }')

Tags: formatistypewithevaltclsecondsprint
1条回答
网友
1楼 · 发布于 2024-06-23 03:30:27

这是Tkinter猜测字符串类型的方式的问题。你知道吗

在Tcl中,空列表和空字符串之间没有什么有意义的区别,因此字节码编译器可以随意更改内部类型,这对Tcl来说是最方便的。你知道吗

Tcl在C实现中使用了一个Tcl_Obj结构,它最多可以同时保存两个类型信息(一个总是string,另一个是Tcl解释器的当前视图,这取决于对象的最后一次使用)。你知道吗

因此,如果一些代码试图“猜测”Tcl对象的类型,它会执行以下(不可靠)技巧,它会查看Tcl对象的内部值,并假设如果设置了类型指针,则该对象就是该类型。你知道吗

所以看这个:

import Tkinter
tclsh = Tkinter.Tcl()
tclsh.eval('set x ""')
v = tclsh.getvar('x')
print type(v)
tclsh.eval('lindex $x 0')
v = tclsh.getvar('x')
print type(v)

首先是“str”,然后是“tuple”。所以,如果使用变量作为列表,就会发生这种情况,但是为什么它会修改procs返回值呢?你知道吗

这是由于字节编译时的激进的文本共享造成的。空字符串是一种常见的文本,通常只有一个对象(比如PythonsNone或小整数)。你知道吗

您可以使用一个小技巧来解决这个问题,如果您真的需要,只需显式地强制进行类型转换(称为'shimming'seehttp://wiki.tcl.tk/3033)。你知道吗

例如,如果要强制使用整数内部表示,在Tcl中:

set x "2"
incr x 0
# X now has internal type Integer

lindex $x 0
# X now has internal type tuple

append x ""
# X now has the internal type unicode

等等。当您尝试映射两种语言类型的系统时,如果它们有很大的不同,您会在DBAPI层中看到类似的效果到sqlite,或者尝试通过xmlrpc或json调用函数,这是一个怪癖。你知道吗

相关问题 更多 >

    热门问题