Tcl 执行子流程:将PYTHONPATH传递给子流程
当我执行Python脚本并确保PYTHONPATH被正确设置为引用依赖模块时。在Python代码中,我调用一个TCL脚本,它再次调用Python脚本,如下所示:Tcl 执行子流程:将PYTHONPATH传递给子流程,tcl,Tcl,当我执行Python脚本并确保PYTHONPATH被正确设置为引用依赖模块时。在Python代码中,我调用一个TCL脚本,它再次调用Python脚本,如下所示: if {[catch {exec {*}[auto_execok python] [file nativename [file join [file dirname [info script]] my.py ]] } result] == 0 } { puts "Executed successfully $result"
if {[catch {exec {*}[auto_execok python] [file nativename [file join [file dirname [info script]] my.py ]] } result] == 0 } {
puts "Executed successfully $result"
} else {
puts "Error $result"
return error
}
我能够成功地在外部执行Python脚本my.py,但从TCL脚本执行时会出现问题。不知何故,我发现这是因为调用Python脚本时PYTHONPATH未正确传递的原因,因为my.py引用了depdency Python模块
如何在exec命令中传递PYTHONPATH?PYTHONPATH是一个环境变量。它们通过
env
全局变量进行操作:
# You might be able to set this once for your whole script
set python_path {C:/Python/3.6/wherever C:/Users/me/Python/3.6/wherever}
# Transform a Tcl list into the right format that Python expects
set ::env(PYTHONPATH) [join [lmap p $python_path {file nativename $p}] \
$::tcl_platform(pathSeparator)]
# Split this out for a shorter line length. ;-)
set my_py [file join [file dirname [info script]] my.py]
if {[catch {exec {*}[auto_execok python] [file nativename $my_py]} result] == 0 } {
puts "Executed successfully $result"
} else {
puts "Error $result"
return error
}
在Tcl 8.5中,您没有lmap
或Tcl_平台
的pathSeparator
元素,而是执行如下操作:
foreach p $python_path {
if {[info exist ::env(PYTHONPATH)]} {
# Assume Windows
append ::env(PYTHONPATH) ";" [file nativename $p]
} else {
set ::env(PYTHONPATH) [file nativename $p]
}
}
如果值只是一个或两个元素,也可以对其进行硬编码。请记住反斜杠(\
)对Tcl很重要,因此,如果要这样做,请将字符串放在{
..}
中
set ::env(PYTHONPATH) {C:\Python\3.6\wherever;C:\Users\me\Python\3.6\wherever}
这对于任何可再发行的东西来说都不是特别可行的……但对自己的脚本有效。PYTHONPATH是一个环境变量。它们通过
env
全局变量进行操作:
# You might be able to set this once for your whole script
set python_path {C:/Python/3.6/wherever C:/Users/me/Python/3.6/wherever}
# Transform a Tcl list into the right format that Python expects
set ::env(PYTHONPATH) [join [lmap p $python_path {file nativename $p}] \
$::tcl_platform(pathSeparator)]
# Split this out for a shorter line length. ;-)
set my_py [file join [file dirname [info script]] my.py]
if {[catch {exec {*}[auto_execok python] [file nativename $my_py]} result] == 0 } {
puts "Executed successfully $result"
} else {
puts "Error $result"
return error
}
在Tcl 8.5中,您没有lmap
或Tcl_平台
的pathSeparator
元素,而是执行如下操作:
foreach p $python_path {
if {[info exist ::env(PYTHONPATH)]} {
# Assume Windows
append ::env(PYTHONPATH) ";" [file nativename $p]
} else {
set ::env(PYTHONPATH) [file nativename $p]
}
}
如果值只是一个或两个元素,也可以对其进行硬编码。请记住反斜杠(\
)对Tcl很重要,因此,如果要这样做,请将字符串放在{
..}
中
set ::env(PYTHONPATH) {C:\Python\3.6\wherever;C:\Users\me\Python\3.6\wherever}
这对于任何可再发行的东西来说都不是特别可行的……但对自己的脚本有效。似乎lmap在TCL 8.5中不可用-尽管有一个问题我们可以像[auto_execok PYTHON--pythonpath$systempypath]那样传递PYTHON路径吗…不在
auto_execok
调用中。似乎lmap在TCL 8.5中不可用-尽管有一个问题我们可以像[auto_execok PYTHON--pythonpath$systempypath]那样传递PYTHON路径…不在auto_execok
调用中。