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

时间:2013-08-01 23:10:19

标签: python python-2.7

如何将字典作为命令行参数传递给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中创建字典。

5 个答案:

答案 0 :(得分:47)

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

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

JSON - 或JavaScript Object Representation是一种获取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。)

答案 1 :(得分:9)

这是使用sdtin的另一种方法。这就是你想要的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

答案 2 :(得分:0)

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

因此,我决定在参数级别对字符串进行url编码,然后在Python脚本中对其进行解码。这意味着调用python脚本的任何内容都需要对JSON字符串的命令行参数进行url编码。有许多online tools使您可以对字符串进行url编码的沙箱。就我而言,nodejs脚本会调用python脚本调用,并且可以轻松地对JSON进行网址编码。

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)

答案 3 :(得分:0)

请按照以下步骤将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'}

答案 4 :(得分:0)

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

的 python 文件
import sys
i = sys.argv[1]
a = eval(i)
print(a)
print(type(a))

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

python somepyfile.py {'hello':4}

简单正确!