[英]Passing arguments to execfile in python 2.7
I need to call one python script from another script,I'm trying to do it with the help of execfile function.I need to pass a dictionary as an argument to the calling function.Is there any possibility to do that? 我需要从另一个脚本中调用一个python脚本,我想在execfile函数的帮助下进行操作。我需要将字典作为参数传递给调用函数。是否有可能这样做?
import subprocess
from subprocess import Popen
-------To read the data from xls-----
ret_lst = T_read("LDW_App05")
for each in ret_lst:
lst.append(each.replace(' ','-'))
lst.append(' ')
result = Popen(['python','LDW_App05.py'] + lst ,stdin = subprocess.PIPE,stdout = subprocess.PIPE).communicate()
print result
Here,in the above code I'm reading the Input data from the Excel sheet in the form of list,I need to pass the list as an argument to LDW_App05.py file 在这里,在上面的代码中,我以列表的形式从Excel工作表中读取输入数据,我需要将列表作为参数传递给LDW_App05.py文件
Instead of passing complex data as CL arguments, I propose piping your data via the STDIN/STDOUT - then you don't need to worry about escaping special, shell-significant chars and exceeding the maximum command line length. 我建议不要通过STDIN / STDOUT通过管道传递数据,而不是将复杂的数据作为CL参数传递,这样您就不必担心转义特殊的,对shell有意义的字符并超过最大命令行长度。
Typically, as CL argument-based script you might have something like app.py
: 通常,作为基于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__))
It clearly expects an argument to be passed and it will print it out if passed from another script, say caller.py
: 显然,它希望传递一个参数,并且如果从另一个脚本(如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
But what if you want to pass something more complex, let's say a dict
? 但是,如果您想传递更复杂的内容,比如说一个dict
怎么办? Since a dict
is a hierarchical structure we'll need a way to present it in a single line. 由于dict
是分层结构,因此我们需要一种将其显示在一行中的方法。 There are a lot of formats that would fit the bill, but let's stick to the basic JSON, so you might have your caller.py
set to something like this: 有很多格式caller.py
要求,但是让我们坚持使用基本的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"}}
Now if you modify your app.py
to recognize the fact that it's receiving JSON as an argument you can deserialize it back to Python dict
to access its structure: 现在,如果您修改app.py
以识别它正在接收JSON作为参数的事实,则可以将其反序列化回Python dict
以访问其结构:
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__))
Then if you run your caller.py
again you'll get: 然后,如果再次运行caller.py
,您将获得:
First name: foo Last name: bar
But this is very tedious and JSON is not very friendly to the CL (behind the scenes Python does a ton of escaping to make it work) not to mention there is a limit (OS and shell depending) on how big your JSON can be passed this way. 但这非常繁琐,而且JSON对CL不太友好(在幕后Python进行了大量转义以使其正常工作),更不用说JSON可以传递的大小有一个限制(取决于操作系统和外壳)这条路。 It's much better to use STDIN/STDOUT buffer to pass your complex data between processes. 最好使用STDIN / STDOUT缓冲区在进程之间传递复杂的数据。 To do so, you'll have to modify your app.py
to wait for input on its STDIN, and for caller.py
to send serialized data to it. 为此,您必须修改app.py
以等待其STDIN上的输入,并要求caller.py
向其发送序列化数据。 So, app.py
can be as simple as: 因此, 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
and caller.py
: 和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
and if you invoke caller.py
you again get: 如果您调用caller.py
您将再次得到:
First name: foo Last name: bar
But this time there is no limit to the data size you're passing over to your app.py
and you don't have to worry if a certain format would be messed up during shell escaping etc. You can also keep the 'channel' open and have both processes communicate with each other in a bi-directional fashion - check this answer for an example. 但是这次,您传递给app.py
的数据大小没有限制,您不必担心在转义外壳等过程中是否会弄乱某种格式。您还可以保留“通道”打开并让两个进程以双向方式相互通信-请查看此答案以获取示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.