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

如何将字典作为命令行参数传递给Python脚本?,python,python-2.7,command-line,Python,Python 2.7,Command Line,如何将字典作为命令行参数传递给Python脚本? 我需要得到字典,其中键是字符串,值是一些元素的列表 –例如,看起来像: command_line_arguments = {"names" : ["J.J.", "April"], "years" : [25, 29]} 我已经试过了 if __name__ == '__main__': args = dict([arg.split('=') for arg

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

这里需要注意的重要一点是,在命令行中,不能将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]}'


请注意,引用内容是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
echo { "key1": "value 1", "key2": "value 2" } | python myscript.py
要从Windows终端测试脚本,请执行以下操作:

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

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

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

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


按照以下步骤读取
JSON
Dictionary
作为命令行参数,而不必转义Python的双引号或单引号:

  • 像这样导入python的Windows32 API模块:
    导入win32.win32api


    如果尚未安装模块,请键入:
    pip install pywin32
    在您的计算机中安装此模块。

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

    cmdArguments=win32.win32api.GetCommandLine()


  • 在命令行参数的最后一个参数中传递
    JSON/Dictionary
    始终是一个很好的做法,因此假设您将
    JSON/Dictionary
    作为命令行中的最后一个参数传递,然后,以下行可以获取
    JSON/Dictionary
    作为单独的参数,并且
    JSON/Dictionary
    将存储在名为
    jsonstr
    的变量中,如下所示:

    jsonstr=''.join(cmdArguments.split('')[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.
    
  • 示例命令行参数如下所示,其中
    NameOfProgram
    是python脚本的名称:

    py{“Name”:“Sample Name”,“Salary”:“20k”,“Class”:“First Class”}


    现在输出为:

    {'Name':'Sample Name','Salary':'20000','Class':'First-Class'}

  • 相关问题:我在centos 6.4、kde konsole、tcsh shell上试过这个,不知道为什么不起作用。python 2.6.6。sys.argv看起来像这样
    [filename,names',“J.J.”,“April',“years',25,29]
    这很好用,但别忘了转义引号,否则Python永远看不到它们。例如,我必须这样做
    ——names“{\“names\”:[\“J.J.”