如何将字典作为命令行参数传递给 python 脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18006161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass dictionary as command line argument to python script?
提问by PaolaJ.
How to pass dictionary as command line argument to python script ? I need to get dictionary where key is string and value is list of some elements ( for example to look like :
如何将字典作为命令行参数传递给 python 脚本?我需要获取字典,其中键是字符串,值是某些元素的列表(例如看起来像:
command_line_arguments = {"names" : ["J.J.", "April"], "years" : [25, 29]}
I have tried like
我试过像
if __name__ == '__main__':
args = dict([arg.split('=') for arg in sys.argv[2:]]) # also tried with 1 but doesn't work
main(args)
and I am calling script like
我正在调用脚本
$ python saver.py names=["J.J.", "April"] years=[25, 29]
but it doesn't work, dictionary has length 0 and need 2. Can anyone help me to pass and create dictionary in main.
但它不起作用,字典的长度为 0 并且需要 2。任何人都可以帮助我在 main 中传递和创建字典。
回答by chander
The important thing to note here is that at the command line you cannot pass in python objects as arguments. The current shell you are using will parse the arguments and pass them in according to it's own argument parsing rules.
这里要注意的重要一点是,在命令行中,您不能将 python 对象作为参数传递。您正在使用的当前 shell 将解析参数并根据它自己的参数解析规则将它们传递进来。
That being said, you cannot pass in a python dictionary. However, things like JSON can allow you to get pretty darn close.
话虽如此,您不能传入 python 字典。然而,像 JSON 这样的东西可以让你非常接近。
JSON - or JavaScript Object Representation is a way of taking Python objects and converting them into a string-like representation, suitable for passing around to multiple languages. That being said, you could pass in a string like this:
JSON - 或 JavaScript 对象表示是一种获取 Python 对象并将它们转换为类似字符串的表示的方法,适用于传递到多种语言。话虽如此,您可以传入这样的字符串:
python saver.py '{"names": ["J.J.", "April"], "years": [25, 29]}'
In your python script, do this:
在您的 python 脚本中,执行以下操作:
import json
data=json.loads(argv[1])
This will give you back a dictionary representing the data you wanted to pass in.
这会给你一个字典,代表你想要传入的数据。
Likewise, you can take a python dictionary and convert it to a string:
同样,您可以使用 Python 字典并将其转换为字符串:
import json
data={'names': ["J.J.", "April"], 'years': [25,29]}
data_str=json.dumps(data)
There are other methods of accomplishing this as well, though JSON is fairly universal. The key thing to note is that regardless of how you do it - you won't be passing the dictionary into Python, - you'll be passing in a set of arguments (which will all be strings) that you'll need to somehow convert into the python type you need.
尽管 JSON 相当普遍,但还有其他方法可以实现这一点。需要注意的关键是,无论你如何做 - 你不会将字典传递给 Python, - 你将传递一组参数(它们都是字符串),你需要以某种方式转换成你需要的python类型。
@EvanZamir - note that (generally) in a shell, you need to escape quotes if they appear in your quoted string. In my example, I quote the JSON data with single quotes, and the json string itself uses double quotes, thereby obviating the need for quotes.
@EvanZamir - 请注意(通常)在 shell 中,如果引号出现在带引号的字符串中,则需要对引号进行转义。在我的示例中,我用单引号引用了 JSON 数据,而 json 字符串本身使用了双引号,从而避免了使用引号的需要。
If you mix quotes (use double quotes to quote the argument, and double quotes inside), then the shell will require it to be escaped, otherwise the first double quote it encounters is considered the "closing quote" for the argument. Note in the example, I use single quotesto enclose the JSON string, and double quoteswithin the string. If I used single quotes in the string, I would need to escape them using a backslash, i.e.:
如果混合引号(使用双引号引用参数,并在其中使用双引号),则 shell 将要求对其进行转义,否则它遇到的第一个双引号将被视为参数的“结束引号”。请注意,在示例中,我使用单引号将 JSON 字符串括起来,并在字符串中使用双引号。如果我在字符串中使用单引号,则需要使用反斜杠将它们转义,即:
python saver.py '{"names": ["J.J.", "April\'s"], "years": [25, 29]}'
or
或者
python saver.py "{\"names\": [\"J.J.\", \"April's\"], \"years\": [25, 29]}"
Note the quoting stuff is a function of your shell, so YMMV might vary (for example, if you use some exec method to call the script, escaping might not be required since the bash shell might not be invoked.)
请注意,引用内容是您的 shell 的一个函数,因此 YMMV 可能会有所不同(例如,如果您使用某些 exec 方法来调用脚本,则可能不需要转义,因为可能不会调用 bash shell。)
回答by BuvinJ
Here's another method using stdin. That's the method you want for a json cgi interface (i.e. having a web server pass the request to your script):
这是使用stdin的另一种方法。这是您想要的 json cgi 接口的方法(即让网络服务器将请求传递给您的脚本):
Python:
Python:
import json, sys
request = json.load( sys.stdin )
...
To test your script from a Linux terminal:
要从 Linux 终端测试您的脚本:
echo '{ "key1": "value 1", "key2": "value 2" }' | python myscript.py
To test your script from a Windows terminal:
要从 Windows 终端测试您的脚本:
echo { "key1": "value 1", "key2": "value 2" } | python myscript.py
回答by Kohanz
I started off with @chander's excellent answer, but was running into issues with special character escaping, both at the shell/command level and within the python script. Saving the JSON
to a file and then passing that filename as a parameter to the script would be a possible solution, but in my situation that was going to be rather complicated.
我从@chander 的优秀答案开始,但在 shell/命令级别和 python 脚本中遇到了特殊字符转义问题。将 保存JSON
到一个文件,然后将该文件名作为参数传递给脚本将是一个可能的解决方案,但在我的情况下,这将是相当复杂的。
So instead I decided to url encode the string at the argument level and decode it inside the Python
script. This means that whatever is calling the python script needs to url-encode the command-line argument that is the JSON
string. There are numerous online toolsthat let you sandbox with url-encoding a string. In my case, a nodejs
script invokes the python script call and can easily url encode the JSON
.
因此,我决定在参数级别对字符串进行 url 编码,并在Python
脚本中对其进行解码。这意味着调用 python 脚本的任何东西都需要对作为JSON
字符串的命令行参数进行 url 编码。有许多在线工具可以让您对字符串进行 url 编码。就我而言,nodejs
脚本调用 python 脚本调用,并且可以轻松地对JSON
.
Inside the Python
script, it looks like this (you don't have to use argparse
, but I like it):
在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)