我正在Go中构建一个工具,该工具需要提供一种方法来解析在Python脚本的全局范围内声明的变量。将来,我也想将其扩展到Node.js。它必须是跨平台的。
基本上,如果有人要使用以下Python代码:
#!/usr/bin/env python
hello = "world"
some_var = "one"
another_var = "two"
var_three = some_func()
我想在我的Golang代码中访问这些变量键和值。对于该函数,我想访问它返回的值。
我当前的想法是使用Golang exec.Command
函数运行脚本,并以某种格式(例如JSON)将变量打印到其stdout上,而后者又可以用Golang进行解析。有想法吗?
答案 0 :(得分:2)
它们具有不同的运行时环境。 Golang无法在Python的运行时中直接访问变量。反之亦然。但是,您可以对其进行编程,以通过标准I / O或环境变量传递变量值。关键是确定信息交换的正确格式。
例如,如果python脚本将参数作为输入并将结果编码为JSON,则输出到stdout。然后,您可以使用适当的参数调用脚本,并将标准输出解码为JSON。
例如:
import json
import sys
def toNum(str):
return int(str)
def main(argv):
# Basically called range() with all the arguments from script call
print(json.dumps(list(range(*map(toNum, argv)))))
if __name__ == '__main__':
main(sys.argv[1:])
package main
import (
"encoding/json"
"fmt"
"log"
"os/exec"
)
func pythonRange(start, stop, step int) (c []byte, err error) {
return exec.Command(
"python3",
"./range.py",
fmt.Sprintf("%d", start),
fmt.Sprintf("%d", stop),
fmt.Sprintf("%d", step),
).Output()
}
func main() {
var arr []int
// get the output of the python script
result, err := pythonRange(1, 10, 1)
if err != nil {
log.Fatal(err)
}
// decode the stdout of the python script
// as a json array of integer
err = json.Unmarshal(result, &arr)
if err != nil {
log.Fatal(err)
}
// show the result with log.Printf
log.Printf("%#v", arr)
}
要将Python中的全局变量作为JSON对象输出:
import json
def dump_globals():
# Basically called range() with all the arguments from script call
vars = dict()
for (key, value) in globals().items():
if key.startswith("__") and key.endswith("__"):
continue # skip __varname__ variables
try:
json.dumps(value) # test if value is json serializable
vars[key] = value
except:
continue
print(json.dumps(vars))
foo = "foo"
bar = "bar"
dump_globals()
输出:
{"foo": "foo", "bar": "bar"}
对于此脚本,您可以使用与上一个类似的main():
import (
"encoding/json"
"fmt"
"log"
"os/exec"
)
func pythonGetVars() (c []byte, err error) {
return exec.Command(
"python3",
"./dump_globals.py",
).Output()
}
func main() {
var vars map[string]interface{}
// get the output of the python script
result, err := pythonGetVars()
if err != nil {
log.Fatal(err)
}
// decode the json object
err = json.Unmarshal(result, &vars)
if err != nil {
log.Fatal(err)
}
// show the result with log.Printf
fmt.Printf("%#v", vars)
}
输出:
map[string]interface {}{"bar":"bar", "foo":"foo"}