代替经过复杂的数据作为CL参数,我建议通过标准输入/输出管道您的数据 - 那么你就不需要担心转义特殊,壳显著字符和超过最大命令行长度。
通常情况下,作为CL参数为基础的脚本,你可能会有诸如app.py
:
import sys
if __name__ == "__main__": # ensure the script is run directly
if len(sys.argv) > 1: # if at least one CL argument was provided
print("ARG_DATA: {}".format(sys.argv[1])) # print it out...
else:
print("usage: python {} ARG_DATA".format(__file__))
它清楚地期待一个参数传递,如果从另一个脚本通过将它打印出来,说caller.py
:
import subprocess
out = subprocess.check_output(["python", "app.py", "foo bar"]) # pass foo bar to the app
print(out.rstrip()) # print out the response
# ARG_DATA: foo bar
但是,如果你想通过更复杂的东西,比方说,一个dict
?由于dict
是一个层次结构,我们需要一种方法将其呈现在一行中。有很多的格式,将符合该法案,但我们坚持自己最基本的JSON,所以你可能也有caller.py
设置为这样的事情:
import json
import subprocess
data = { # our complex data
"user": {
"first_name": "foo",
"last_name": "bar",
}
}
serialized = json.dumps(data) # serialize it to JSON
out = subprocess.check_output(["python", "app.py", serialized]) # pass the serialized data
print(out.rstrip()) # print out the response
# ARG_DATA: {"user": {"first_name": "foo", "last_name": "bar"}}
现在,如果您修改app.py
承认的事实,它接收JSON作为参数,你可以反序列化在Python dict
来访问它的结构:如果您运行caller.py
import json
import sys
if __name__ == "__main__": # ensure the script is run directly
if len(sys.argv) > 1:
data = json.loads(sys.argv[1]) # parse the JSON from the first argument
print("First name: {}".format(data["user"]["first_name"]))
print("Last name: {}".format(data["user"]["last_name"]))
else:
print("usage: python {} JSON".format(__file__))
话又说回来,你会得到:
First name: foo
Last name: bar
但是,这是非常繁琐和JSON是不是到CL(幕后Python做一吨逸出,使工作的),更不用说有上有多大的限制(OS和外壳根据)非常友好的JSON可以通过这种方式传递。使用STDIN/STDOUT缓冲区在进程间传递复杂数据要好得多。要做到这一点,你就必须修改您的app.py
等待它的STDIN输入,并为caller.py
到串行数据发送给它。因此,app.py
可以简单:
import json
if __name__ == "__main__": # ensure the script is run directly
try:
arg = raw_input() # get input from STDIN (Python 2.x)
except NameError:
arg = input() # get input from STDIN (Python 3.x)
data = json.loads(arg) # parse the JSON from the first argument
print("First name: {}".format(data["user"]["first_name"])) # print to STDOUT
print("Last name: {}".format(data["user"]["last_name"])) # print to STDOUT
和caller.py
:
import json
import subprocess
data = { # our complex data
"user": {
"first_name": "foo",
"last_name": "bar",
}
}
# start the process and pipe its STDIN and STDOUT to this process handle:
proc = subprocess.Popen(["python", "app.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
serialized = json.dumps(data) # serialize data to JSON
out, err = proc.communicate(serialized) # send the serialized data to proc's STDIN
print(out.rstrip()) # print what was returned on STDOUT
,如果你调用caller.py
您重新开始:
First name: foo
Last name: bar
但这次没有限制您传递给app.py
的数据大小,并且您不必担心在shell转义过程中某种格式会被搞乱。TC也可以保持“通道”开放,并有两个过程相互的双向沟通方式 - 检查this answer为例。
首先解释为什么要通过的execfile做到这一点。 –
关于该文档:https://docs.python.org/2/library/functions.html#execfile 有“全球”“本地”参数应该可以帮助你 – Benjamin
我正在开发一个脚本,它将读取输入和做一些进程,并调用另一个python脚本的处理结果作为参数。我试图使用os.system,subprocess.popen和subprocess.call这在我的情况下不起作用 – surya