58

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

4

6 回答 6

81

这里要注意的重要一点是,在命令行中,您不能将 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。)

于 2013-08-02T00:22:37.140 回答
15

这是使用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
于 2016-04-06T21:17:33.210 回答
2

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

因此,我决定在参数级别对字符串进行 url 编码,并在Python脚本中对其进行解码。这意味着调用 python 脚本的任何内容都需要对作为JSON字符串的命令行参数进行 url 编码。有许多在线工具可让您使用对字符串进行 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)
于 2019-10-16T20:28:06.643 回答
1

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

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

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

python somepyfile.py {'hello':4}

简单对!

于 2021-07-08T22:03:22.390 回答
0

按照以下步骤阅读JSON或阅读Dictionary命令行参数,甚至无需转义 Python 的双引号或单引号:

  1. 像这样导入适用于 python 的 Windows32 API 模块:
    import win32.win32api

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

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

    cmdArguments = win32.win32api.GetCommandLine()

  3. 在命令行参数中传递最后一个参数始终是一个好习惯JSON/Dictionary,因此假设如果您在命令行中将传递的最后一个参数作为最后一个参数JSON/Dictionary,那么下面的行可以将一个像这样命名的变量: 从技术上讲,对象被分割成单独的参数,因为我们需要将它组合成一个单独的参数。JSON/DictionaryJSON/Dictionaryjsonstr

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

    whitespaces

  4. 现在,如果您打印jsonstrthen 的值,您将得到与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. 示例命令行参数如下所示,NameOfProgrampython 脚本的名称在哪里:

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

    现在输出将是:

    {'Name':'Sample Name','Salary':'20 k','Class':'First-Class'}
于 2020-07-29T08:59:22.843 回答
0

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

"{'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)))

 
于 2022-02-11T06:44:04.727 回答