【问题标题】:Can I pass a list of lists from Node to python easily?我可以轻松地将列表从 Node 传递到 python 吗?
【发布时间】:2019-06-21 01:43:12
【问题描述】:

我知道通过 CLI 将更复杂的数据结构(例如列表列表)传递给 python 脚本存在一些问题。

我想知道从节点代码运行 python 脚本是否有任何这些相同的问题。

基本上,假设我在节点应用程序中有以下代码:

const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',["path/to/script.py", arg1, arg2, arg3]);

Question the above code is from

假设 arg1 和 arg2 是节点应用程序中的列表列表。并假设 arg3 是双精度数。

我的 script.py 文件中用于解析这些参数并将其接收到变量中的相应代码如下所示:

import sys
if __name__ == '__main__':
    oc = sys.argv[1]
    nc = sys.argv[2]
    r = sys.argv[3]

这里的 oc 和 nc 会是 python 中的列表列表吗?或者是否需要做其他事情才能使其正常工作?

【问题讨论】:

  • 不,它们将永远是 str 对象。你可以自己检查一下。为什么不考虑像 JSON 这样的基于文本的序列化格式?
  • 如果 arg1 和 arg2 在 node 传入时是 JSON 对象,会起作用吗?
  • 不,不会。 它们将永远是str 对象。同样,这很容易验证。但是 JSON 是一种数据传输格式。这就是它的用途。

标签: python node.js command-line-interface sys


【解决方案1】:

传递复杂结构最简单的方法是先将其序列化成一些常见的数据格式,比如JSON:

const myList = ["foo", "bar", "baz"];
const { spawn } = require("child_process");
const python = spawn('python',["script.py", JSON.stringify(myList)]);

并在被调用方反序列化:

import sys, json

if __name__ == '__main__':
    my_list = json.loads(sys.argv[1])

但是,与其将序列化参数作为被调用参数传递,不如使用stdoutstdin 流来交换大于几百字节的数据:

const { spawn } = require("child_process");

const python = spawn('python', ["script.py"]);
const buffers = [];

python.stdout.on('data', (chunk) => buffers.push(chunk));
python.stdout.on('end', () => {
    const result = JSON.parse(Buffer.concat(buffers));
    console.log('Python process exited, result:', result);
});

python.stdin.write(JSON.stringify(["foo", "bar", "baz"]));
python.stdin.end()

并通过json.loadsys.stdin 接受它,它接受流而不是字符串:

import sys, json

if __name__ == '__main__':
    my_list = json.load(sys.stdin)
    json.dump(my_list, sys.stdout)

【讨论】:

  • 谢谢!快速提问。我将如何使用您展示的更好的方法来传递多个不同的变量,这些变量是使用 stdout 和 stdin 流的列表?这个例子只展示了如何传入一个列表。
  • @mark_maker,同样的方法,只是把你需要传入的所有变量都包装在js对象中:const passedVars = { arg1, arg2, myList }; python.stdin.write(JSON.stringify(passedVars))。在 python 方面,此类子句将在 dict 实例中展开,并带有相应的字段:data = json.load(sys.stdin) # data['arg1'], data['arg2'], data['myList']
  • @mark_maker 或者您可以将其作为数组而不是对象传递,并将其直接解构为变量:python.stdin.write(JSON.stringify([arg1, arg2, myList])) ... arg1, arg2, myList = json.load(sys.stdin)。但在这种情况下,python 端解构变量的顺序应该对应于 JS 端数组中项目的顺序,所以我建议坚持使用 object/dict 实例编组的第一种方法,而不是依赖于名称。
  • 那么如何将python列表发送到node js?
  • @LukAron 上面的示例已更新为双向通信。请注意,节点应该明确地将 EOF 传递给 python 标准输入流 (python.stdin.end()),否则 python 进程将无限期地等待更多数据的到来。在复杂的情况下,您可能希望使用其他方法,例如 unix 套接字通信或功能齐全的 IPC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
相关资源
最近更新 更多