【问题标题】:Parsing command line arguments containing dictionaries解析包含字典的命令行参数
【发布时间】:2021-03-20 08:22:23
【问题描述】:

我想将命令行参数传递给包含如下字典的 python:

python server.py --keys '{"0x11": "f1.bin", "0x21": "f2.bin"}' --binaries '{"0x11": "dog.jpg", "0x21": "apple.jpg"}' -d '100' -p '1234'

我希望能够将字典的这些字符串表示形式转换为实际的 Python 字典。

当我在 main 函数中打印出 argv 参数时,我得到一个如下所示的列表:

['--keys', "'{0x11:", 'f1.bin,', '0x21:', "f2.bin}'", '--binaries', "'{0x11:", 'cat.jpg,', '0x21:', "kitten.jpg}'", '-d', "'100'", '-p', "'1234'"]

这不是所需的输出。例如,请注意字典的键周围不再有引号。因此,我不能使用jsonast 包将字典的字符串表示形式转换为实际字典。我希望字典的整个字符串表示形式是列表中的单个元素,并保留它们的结构。

我尝试过使用optparse 包,但是,这也无济于事。以下是我尝试的方法:

def main(argv):

    parser = optparse.OptionParser()
    parser.add_option('--keys')
    parser.add_option('--binaries')
    parser.add_option('-d')
    parser.add_option('-p')

    options, args = parser.parse_args()
    print(argv)
    print(options)
    print(args)

它给出以下输出:

['--keys', "'{0x11:", 'f1.bin,', '0x21:', "f2.bin}'", '--binaries', "'{0x11:", 'cat.jpg,', '0x21:', "kitten.jpg}'", '-d', "'100'", '-p', "'1234'"]
{'keys': "'{0x11:", 'binaries': "'{0x11:", 'd': "'100'", 'p': "'1234'"}
['f1.bin,', '0x21:', "f2.bin}'", 'cat.jpg,', '0x21:', "kitten.jpg}'"]

有没有一种简单的方法来实现我想要的输出?或者在使用jsonast 之前,我是否需要编写自己的代码来改变 argv 的元素,使其看起来像我想要的样子?


注意 莫里斯的解决方案是完美的。起初它引起了一些麻烦,直到他注意到我的问题实际上只发生在 Windows 上。在 Windows 上,我们必须用双引号将字典括起来,并像这样转义内部的双引号:

python server.py --keys "{\"0x11\": \"f1.bin\", \"0x21\": \"f2.bin\"}" --binaries"{\"0x11\": \"dog.jpg\", \"0x21\": \"apple.jpg\"}" -d '100' -p '1234'
Huge thanks to him, because I never would have figured this issue out on my own.

【问题讨论】:

    标签: python command-line command-line-arguments


    【解决方案1】:

    使用argparse(不推荐使用optparse),选项可以有一个类型(intstr,...)。但是你可以使用json.loadsast.literal_eval作为type来解析JSON字符串:

    import ast
    import json
    import argparse
    
    parser = argparse.ArgumentParser(description='JSON TEST')
    parser.add_argument('--keys', type=ast.literal_eval)
    parser.add_argument('--binaries', type=json.loads)
    parser.add_argument('-d', type=str)
    parser.add_argument('-p', type=str)
    
    args = parser.parse_args()
    print(args)
    

    从 CLI 调用:

    python server.py --keys '{"0x11": "f1.bin", "0x21": "f2.bin"}' --binaries '{"0x11": "dog.jpg", "0x21": "apple.jpg"}' -d '100' -p '1234'   
    

    输出:

    Namespace(binaries={'0x11': 'dog.jpg', '0x21': 'apple.jpg'}, d='100', keys={'0x11': 'f1.bin', '0x21': 'f2.bin'}, p='1234')
    

    注意:
    在 Windows 上,您需要转义 JSON 字符串中的引号:

    python server.py --keys "{\"0x11\": \"f1.bin\", \"0x21\": \"f2.bin\"}" --binaries "{\"0x11\": \"dog.jpg\", \"0x21\": \"apple.jpg\"}" -d '100' -p '1234'
    

    输出:

    【讨论】:

    • 这给了我以下输出:'{0x11:^SyntaxError: EOL while scanning string literal
    • 复制和粘贴您在问题中提到的 CLI 命令在 Python27/38 和 39 上对我来说效果很好。
    • 我目前正在运行 python 3.7
    • 如果我将第一次调用 parse.add_argument 中的类型更改为 json.loads,则错误变为server.py: error: argument --keys: invalid loads value: "'{0x11:"
    • 你能展示你在 CLI 上执行的内容(整个命令)吗?
    猜你喜欢
    • 1970-01-01
    • 2020-05-24
    • 2011-05-17
    • 2013-03-21
    • 1970-01-01
    相关资源
    最近更新 更多