简体   繁体   English

在python 2.7中将参数传递给execfile

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM