【问题标题】:Passing arguments to execfile in python 2.7在python 2.7中将参数传递给execfile
【发布时间】:2017-12-24 10:07:55
【问题描述】:

我需要从另一个脚本调用一个 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

在上面的代码中,我以列表的形式从 Excel 工作表中读取输入数据,我需要将列表作为参数传递给 LDW_App05.py 文件

【问题讨论】:

  • 先解释一下为什么要通过execfile来做这个。
  • 关于文档:docs.python.org/2/library/functions.html#execfile 有“全局”“本地”参数应该可以帮助您
  • 我正在开发一个脚本,它将读取输入并执行一些过程,并以处理后的结果作为参数调用另一个 python 脚本。我尝试使用 os.system、subprocess.popen 和 subprocess。在我的情况下不起作用的电话
  • 您可能希望共享您的 subprocess.popen 方法以及您希望在 2 个脚本之间共享哪种数据 - 这样更容易有人帮助您。
  • 假设您控制两个脚本,如果您想传递复杂/结构化数据(dictlist 等),为什么不让您的第二个脚本从 STDIN 中提取它呢?然后,您的第一个脚本可以按照您喜欢的任何方式序列化数据,并将其传递给第二个脚本的 STDIN,而没有典型的命令行参数限制。

标签: python parameter-passing execfile


【解决方案1】:

我建议不要将复杂数据作为 CL 参数传递,而是通过 STDIN/STDOUT 管道传输您的数据 - 这样您就不必担心转义特殊的、shell 有效的字符和超过最大命令行长度。

通常,作为基于 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 以访问其结构:

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__))

如果你再次运行caller.py,你会得到:

名字:foo
姓氏:酒吧

但这非常乏味,而且 JSON 对 CL 不是很友好(在幕后 Python 进行了大量的转义以使其工作)更不用说 JSON 的大小有限制(取决于操作系统和 shell)可以通过这种方式。使用 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,你会再次得到:

名字:foo
姓氏:酒吧

但是这次你传递给app.py的数据大小没有限制,你不必担心在shell转义等过程中某种格式会被搞砸。你也可以保留“通道”打开并让两个进程以双向方式相互通信 - 以 this answer 为例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 2014-02-01
    • 2014-02-13
    • 2018-09-29
    相关资源
    最近更新 更多