代替經過複雜的數據作爲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