Stu*_*art 0 python tkinter tcl type-conversion
我正在使用TKinter从Python访问现有的Tcl库.其中一个Tcl过程在列表中查找值,如果未找到该值则返回"".Python代码将返回值视为unicode,并检查它是否等于"".这完全有效,直到在Tcl代码中调用[时钟格式].之后,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)
Run Code Online (Sandbox Code Playgroud)
结果输出是:
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'>
Run Code Online (Sandbox Code Playgroud)
如您所见,只有空字符串受到影响,并且调用[clock]不会导致问题; 只有[时钟格式].
任何帮助将不胜感激.
注意:我尝试了不同的方法来返回空字符串,但它们不会影响输出.我试过了:
_tclsh.eval('proc returnBlank { } { return }')
_tclsh.eval('proc returnBlank { } { return {} }')
Run Code Online (Sandbox Code Playgroud)
这是Tkinter猜测字符串类型的方式的问题.
在Tcl中,空列表或空字符串之间没有任何有意义的区别,因此字节码编译器可以随意更改内部类型,在这种情况下对于Tcl最方便.
Tcl Tcl_Obj在C实现中使用一个结构,它最多可以同时保存两个类型的信息(一个总是字符串,另一个是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)
Run Code Online (Sandbox Code Playgroud)
首先是'str',后来是'tuple'.因此,如果您将变量用作列表,会发生这种情况,但为什么它会修改您的procs返回值?
这是因为字节编译时积极的文字共享.空字符串是一个常见的字面值,通常只有一个对象(如Pythons None或小整数).
你可以使用一个小技巧来解决这个问题,如果你真的需要,只需要强制进行类型转换(称为"闪烁",请参阅http://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
Run Code Online (Sandbox Code Playgroud)
等等.当你尝试映射两种语言类型系统时,如果它们差别很大,你会看到DBAPI层中的类似效果,或者尝试通过xmlrpc或json调用函数时,这是一个怪癖.
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |