繁体   English   中英

如何将字典作为命令行参数传递给 Python 脚本?

[英]How to pass dictionary as command line argument to Python script?

如何将字典作为命令行参数传递给 Python 脚本? 我需要获取字典,其中键是字符串,值是一些元素的列表 - 例如看起来像:

command_line_arguments = {"names" : ["J.J.", "April"], "years" : [25, 29]}

我试过像

if __name__ == '__main__':
    args = dict([arg.split('=') for arg in sys.argv[2:]]) # also tried with 1 but doesn't work
    main(args)

我正在调用脚本

$ python saver.py names=["J.J.", "April"] years=[25, 29]

但它不起作用,字典的长度为 0,需要 2。任何人都可以帮我在 main.js 中传递和创建字典。

这里要注意的重要一点是,在命令行中,您不能将 python 对象作为参数传递。 您正在使用的当前 shell 将解析参数并根据它自己的参数解析规则传递它们。

话虽如此,您不能传入 python 字典。 然而,像 JSON 这样的东西可以让你非常接近。

JSON - 或 JavaScript 对象表示是一种获取 Python 对象并将它们转换为类似字符串的表示的方式,适用于传递给多种语言。 话虽如此,您可以传入这样的字符串:

python saver.py '{"names": ["J.J.", "April"], "years": [25, 29]}'

在您的 python 脚本中,执行以下操作:

import json
data=json.loads(argv[1])

这会给你一个字典,代表你想要传入的数据。

同样,您可以使用 python 字典并将其转换为字符串:

import json
data={'names': ["J.J.", "April"], 'years': [25,29]}
data_str=json.dumps(data)

尽管 JSON 相当普遍,但还有其他方法可以实现这一点。 需要注意的关键是,无论您如何执行此操作 - 您都不会将字典传递给 Python,您将传入一组您需要以某种方式传递的参数(它们都将是字符串)转换成你需要的python类型。

@EvanZamir - 请注意(通常)在shell中,如果引号出现在引用的字符串中,则需要转义它们。 在我的示例中,我用单引号引用 JSON 数据,而 json 字符串本身使用双引号,从而消除了对引号的需要。

如果你混合引号(使用双引号引用参数,并在内部使用双引号),那么 shell 将要求它被转义,否则它遇到的第一个双引号被认为是参数的“结束引号”。 请注意,在示例中,我使用单引号将 JSON 字符串括起来,并在字符串中使用双引号 如果我在字符串中使用单引号,我需要使用反斜杠转义它们,即:

python saver.py '{"names": ["J.J.", "April\'s"], "years": [25, 29]}'

或者

python saver.py "{\"names\": [\"J.J.\", \"April's\"], \"years\": [25, 29]}"

请注意,引用内容是您的 shell 的一个函数,因此 YMMV 可能会有所不同(例如,如果您使用某些 exec 方法来调用脚本,则可能不需要转义,因为可能不会调用 bash shell。)

这是使用stdin的另一种方法。 这就是您想要的 json cgi 接口的方法(即让 Web 服务器将请求传递给您的脚本):

Python:

 import json, sys
 request = json.load( sys.stdin )
...

要从 Linux 终端测试您的脚本:

echo '{ "key1": "value 1", "key2": "value 2" }' | python myscript.py

要从 Windows 终端测试您的脚本:

echo { "key1": "value 1", "key2": "value 2" } | python myscript.py

尽管我的回答已经晚了。 我发现这里的大多数答案都有某种漏洞或不必要的乏味。 我也需要将字典字符串作为命令行参数传递。 所以在这里你去最简单和最确定的方法如下。 它适用于 linux 和 windows 在名为 somepyfile.py 的 python 文件中键入下面

import sys
from ast import literal_eval

i = sys.argv[1]
a = literal_eval(i)
print(a)
print(type(a))

现在在终端中执行以下操作

python somepyfile.py {'hello':4}

简单对!

我从@chander 的出色答案开始,但在 shell/命令级别和 python 脚本中都遇到了特殊字符转义的问题。 JSON保存到文件,然后将该文件名作为参数传递给脚本将是一种可能的解决方案,但在我的情况下,这将是相当复杂的。

因此,我决定在参数级别对字符串进行 url 编码,并在Python脚本中对其进行解码。 这意味着调用 python 脚本的任何东西都需要对作为JSON字符串的命令行参数进行 url 编码。 有许多在线工具可让您使用对字符串进行 url 编码的沙箱。 在我的例子中, nodejs脚本调用 python 脚本调用并且可以轻松地对JSON进行 url 编码。

Python脚本中,它看起来像这样(您不必使用argparse ,但我喜欢它):

import json
import argparse
from urllib.parse import unquote

# Set up CLI Arguments
parser = argparse.ArgumentParser()

# Required Arguments
parser.add_argument("-c", "--config", required=True,
                    help="JSON configuration string for this operation")

# Grab the Arguments
args = parser.parse_args()

jsonString = unquote(args.config)

print(jsonString)

config = json.loads(jsonString)

print(config)

传递命令行参数如下(注意单引号和双引号):

"{'k1':'v1','k2':['v1','v2',1,2,3]}"

然后在你的python代码中使用 eval() 或 ast.literal_eval()

import ast
if __name__=="__main__":
     cmd_arg=sys.argv[1]
     print(ast.literal_eval(cmd_arg))
     print(type(ast.literal_eval(cmd_arg)))

 

按照以下步骤读取JSONDictionary作为命令行参数,甚至无需转义 Python 的双引号或单引号:

  1. 像这样为 python 导入 Windows32 API 模块:
    import win32.win32api

    如果您没有安装该模块,请输入: pip install pywin32以在您的机器中安装此模块。

  2. 读取命令行参数将通过这一行完成,命令行参数的值将作为字符串存储在cmdArguments变量中:

    cmdArguments = win32.win32api.GetCommandLine()

  3. 在命令行参数的最后一个参数中传递JSON/Dictionary始终是一个好习惯,因此假设如果您将JSON/Dictionary作为命令行中的最后一个参数传递,那么以下行可以将JSON/Dictionary获取为一个单独的参数和JSON/Dictionary将存储在一个名为jsonstr的变量中,如下所示:

    jsonstr = ' '.join(cmdArguments.split(' ')[4:])

    从技术上讲,由于whitespaces ,对象被拆分为单独的参数,我们需要将其组合成一个单独的参数。

  4. 现在,如果您打印jsonstr的值,那么您将获得在命令行参数部分中传递的相同JSON/Dictionary

    完整的示例代码是:

     import json import win32.win32api cmdArguments = win32.win32api.GetCommandLine() jsonstr = ' '.join(cmdArguments.split(' ')[4:]) print(json.loads(jsonstr)) #To ensure that same JSON/Dictionary object is printed, json.loads() is used to convert JSON to DICT, you can ignore json.loads() if you want JSON object.
  5. 示例命令行参数如下所示,其中NameOfProgram是 python 脚本的名称:

    py <NameOfProgram.py> {"Name":"Sample Name","Salary":"20 k","Class":"First-Class"}

    现在输出将是:

    {'Name':'Sample Name','Salary':'20 k','Class':'First-Class'}

这应该有效:

script = ["python2.7", os.path.join(os.path.dirname(__file__), "xs_helper.py"), '\'%s\'' % json.dumps(dicData)]

有时你只需要一些简单的东西,没有 json 甚至 literal_eval:

import sys

dict_arg = sys.argv[1]
result = dict( pair.split('=') for pair in dict_arg.split(',') )

print(result)

那里的一些.strip()也可以处理额外的空白。

⏵ python3 parse.py 'foo=bar,number=6'
{'foo': 'bar', 'number': '6'}

我遇到了同样的问题,对我有用的只是使用反斜杠,例如:

"{\"key\": \"value\", \"key2\": [{\"key3\":\"value\"}, ... ]}"

PS 在 Windows 终端 (CMD) 和 Bash (Git Bash) 中测试

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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