如何将字典作为命令行参数传递给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中创建字典。
答案 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)
请按照以下步骤将JSON
或Dictionary
用作命令行参数,而无需为Python加上双引号或单引号:
import win32.win32api
pip install pywin32
将此模块安装到计算机中。cmdArguments
变量中:cmdArguments = win32.win32api.GetCommandLine()
JSON/Dictionary
始终是一个好习惯,因此,假设您在命令行中将JSON/Dictionary
作为最后一个参数传递,则下一行可以将JSON/Dictionary
作为单独的参数来获取,而JSON/Dictionary
将存储在名为jsonstr
的变量中,如下所示:jsonstr = ' '.join(cmdArguments.split(' ')[4:])
whitespaces
,该对象被分成单独的参数,我们需要将其组合以使其成为单个参数。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 <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}
简单正确!