python - 如何使用 Python 3 json.dumps 保持固定的 JSON 键顺序?

标签 python json python-3.x

我注意到在 Python 3 的 json.dumps 实现中有一些奇怪的行为,即每次我从一个执行到另一个执行转储相同的对象时,键的顺序都会改变。谷歌搜索不起作用,因为我不关心对键进行排序,我只希望它们保持不变!这是一个示例脚本:

import json

data = {
    'number': 42,
    'name': 'John Doe',
    'email': 'john.doe@example.com',
    'balance': 235.03,
    'isadmin': False,
    'groceries': [
        'apples',
        'bananas',
        'pears',
    ],
    'nested': {
        'complex': True,
        'value': 2153.23412
    }
}

print(json.dumps(data, indent=2))

当我运行这个脚本时,我每次都会得到不同的输出,例如:

$ python print_data.py 
{
  "groceries": [
    "apples",
    "bananas",
    "pears"
  ],
  "isadmin": false,
  "nested": {
    "value": 2153.23412,
    "complex": true
  },
  "email": "john.doe@example.com",
  "number": 42,
  "name": "John Doe",
  "balance": 235.03
}

然后我再次运行它,我得到:

$ python print_data.py 
{
  "email": "john.doe@example.com",
  "balance": 235.03,
  "name": "John Doe",
  "nested": {
    "value": 2153.23412,
    "complex": true
  },
  "isadmin": false,
  "groceries": [
    "apples",
    "bananas",
    "pears"
  ],
  "number": 42
}

我知道字典是无序的集合,顺序是基于哈希函数的;然而在 Python 2 中——顺序(不管它是什么)是固定的,不会在每次执行时改变。这里的困难在于它让我的测试难以运行,因为我需要比较两个不同模块的 JSON 输出!

知道发生了什么事吗?如何解决?请注意,我想避免使用 OrderedDict 或执行任何排序,重要的是字符串表示在执行之间保持不变。此外,这仅用于测试目的,对我的模块的实现没有任何影响。

最佳答案

Python 字典和 JSON 对象是无序的。您可以请求 json.dumps() 对输出中的键进行排序;这是为了简化测试。使用 sort_keys 参数为 True:

print(json.dumps(data, indent=2, sort_keys=True))

参见 Why is the order in Python dictionaries and sets arbitrary?至于为什么每次看到的顺序都不一样。

您可以设置 PYTHONHASHSEED environment variable到一个整数值来“锁定”字典顺序;仅将其用于运行测试而不用于生产,因为散列随机化的全部意义在于防止攻击者对您的程序进行简单的 DOS 攻击。

关于python - 如何使用 Python 3 json.dumps 保持固定的 JSON 键顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34931386/

相关文章:

json - Mongoose - 无法检索快速 route 的虚拟字段

python - 从 mac 地址转换为十六进制字符串,反之亦然 - python 2 和 3

python - 如果在 Python 中出现异常重试

python - 我想在 vtk(python)中制作均匀分布的球体

javascript - 从令人兴奋的 Nodejs 重新构建 json

python-3.x - 如何获取gensim LDA中所有文档的document_topics分布?

python - 内置 iter() 函数和 for 语句

python - pymc 中的标准化贝叶斯 IRT 模型

python - Django - 禁用系统检查之一

java - AngularJS 和 Servlet 集成