【问题标题】:How we will take the keys from a json in the original order?我们如何以原始顺序从 json 中获取密钥?
【发布时间】:2019-09-25 20:26:49
【问题描述】:

我有一个 JSON 文件,我想将该 JSON 数据处理为键值对。

这是我的 JSON 文件

```"users" : {
        "abc": {
            "ip": "-------------",
            "username": "users@gmail.com",
            "password": "---------",
            "displayname": "-------",
            "Mode": "-----",
            "phonenumber": "1********1",
            "pstndisplay": "+1 *******5"
        },
        "efg": {
            "ip": "-------------",
            "username": "user1@gmail.com",
            "password": "---------",
            "displayname": "-------",
            "Mode": "-----",
            "phonenumber": "1********1",
            "pstndisplay": "+1 *******5"
        },
        "xyz": {
            "ip": "-------------",
            "username": "user2@gmail.com",
            "password": "---------",
            "displayname": "-------",
            "Mode": "-----",
            "phonenumber": "1********1",
            "pstndisplay": "+1 *******5"```

这里我尝试获取json数据

 ``` ${the file as string}=    Get File    ${users_json_path}
  ${parsed}=    Evaluate  json.loads("""${the file as string}""")    json
  ${properties}=  Set Variable  ${parsed["users"]}
  Log  ${properties}
  :FOR    ${key}    IN    @{properties}
  \  ${sub dict}=    Get From Dictionary    ${properties}    ${key}
  \  Log  ${sub dict}
  \  Signin  ${sub dict}[ip]   ${sub dict}[username]   ${sub dict}[password]  ${sub dict}[Mode]
  \  Log  ${key} is successfully signed in.

预期行为 - 我正在解析的键应该从 JSON 文件中按顺序排列。例如,abc 会先登录,然后是 efg 和 xyz。

${key} = abc
${key} = efg
${key} = xyz

以下是问题: 1)我们将如何按顺序从 JSON 中获取用户?现在它正在随机 2) 实现这一目标的最佳逻辑是什么?

【问题讨论】:

  • 字典不保证按任何特定顺序排列。您可能必须手动解析原始字符串。或者更改后端软件以返回字典列表而不是字典。
  • @BryanOakley - 如何在机器人框架中实现这一点?你能举个例子吗?

标签: json python-2.7 robotframework


【解决方案1】:

我看到你用 python 2.7 标记了这个问题 - Bryan Oakely 的评论完全正确,元素是随机顺序的。
但是,如果您升级到 python 3,从 v3.6 开始,保证字典会保留插入顺序。因此,在使用 json 库对其进行解析时,结果将与源字符串/文件中的结果相同。

或者,在 v2 中,您可以使用 OrderedDict 来完成相同的操作 - 另外,将 object_pairs_hook 参数指定为 JSONDecoder - 使用它,您基本上可以指定结果为 OrderedDict

${parsed}=    Evaluate  json.loads("""${the file as string}""", object_pairs_hook=collections.OrderedDict)    json, collections

【讨论】:

  • 我不明白这个 object_pairs_hook=collections.OrderedDict。请您在 RF 中用很少的详细代码解释一下
  • 这实际上是 python,而这 - Evaluate 调用,是 RF 代码的扩展,在 Robot Framework 方面没有什么要添加的 :)。按照我为JSONDecoder 放置的链接,它有object_pairs_hook 的文档,以及它的作用。简化后,生成的对象将不是一个简单的dict,而是一个OrderedDict——一个保留键原始顺序的字典。
  • 非常感谢您的快速回复,现在正在运行。
【解决方案2】:
#!/usr/bin/env python3
import json

def main():
    json_str = """
    {
        "users" : {
            "abc": {
                "ip": "-------------",
                "username": "users@gmail.com",
                "password": "---------",
                "displayname": "-------",
                "Mode": "-----",
                "phonenumber": "1********1",
                "pstndisplay": "+1 *******5"
            },
            "efg": {
                "ip": "-------------",
                "username": "user1@gmail.com",
                "password": "---------",
                "displayname": "-------",
                "Mode": "-----",
                "phonenumber": "1********1",
                "pstndisplay": "+1 *******5"
            }
        }
    }
    """
    json_object = json.loads(json_str)
    for line in json_str.split('\n'):
        if '"' in line and ':' in line and '{' in line and '"users"' not in line:
            key = line.split('"')[1]
            print(key, json_object['users'][key])

【讨论】:

  • 这可能会以多种方式中断...例如,如果生产者生成这样的行 - "Mode": "-----",{。或者,如果 json 被最小化一个 - 单行字符。至少在 if 块中添加另一个检查 - if key in json_object['users'],然后打印。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多