【问题标题】:Why json.dumps() in python 3 return a different value of python 2? [duplicate]为什么 python 3 中的 json.dumps() 返回 python 2 的不同值? [复制]
【发布时间】:2019-01-17 01:12:07
【问题描述】:

我需要在 Python 3 中生成一个 MD5 哈希来与在 Python 2 上生成的 MD5 哈希进行比较,但是 json.dumps() 的结果是不同的,因为在 Python 2 上元素的位置发生了变化并且MD5 结果不同。

我怎样才能产生相同的结果?

代码:

content = {'name': 'Marcelo', 'age': 30, 'address': {'country': 'Brasil'}, 'interests': [{'id': 1, 'description': 'tecnology'}]}

print('CONTENT:', json.dumps(content))

print('MD5:', md5(str(content).encode('UTF-8')).hexdigest())

Python 2.7 结果:

('CONTENT:', {'interests': [{'id': 1, 'description': 'tecnology'}], 'age': 30, 'name': 'Marcelo', 'address': {'country': 'Brasil'}})

('MD5:', 'a396f6997fb420992d96b37e8f37938d')

Python 3.6 结果:

CONTENT: {'name': 'Marcelo', 'age': 30, 'address': {'country': 'Brasil'}, 'interests': [{'id': 1, 'description': 'tecnology'}]}

MD5: 40c601152725654148811749d9fc8878

编辑:

我无法更改在 Python 2 上生成的 MD5。有什么方法可以在 Python 3 上重现 Python 2 的默认顺序?

【问题讨论】:

  • 字典没有排序,因此即使对于相同的 Python 版本也不能保证准确的 json 输出。

标签: python json python-2.7 md5 python-3.6


【解决方案1】:

在 3.6 之前的 Python 中,字典键没有排序。所以在 Python 3.6 中,键保持它们插入的顺序(或者在字典文字的情况下,它们在文字中的出现方式)。 Python 2.7 字典是无序的,因此循环顺序不一定与插入顺序匹配。

如果在这两种情况下都重新加载 json 字典,它仍然是相等的(字典相等不依赖于顺序)。

所以这里没有错误。不同之处在于字典在不同 Python 版本中的排序方式。

json.dumpjson.dumps 按字典循环顺序写出键值对。所以为了有一致的循环顺序,最好使用collections.OrderedDict类型来实现一致的顺序。如果您调用json.load 来获取字典,您还需要使用json.loads(text, object_hook=OrderedDict),这将保持排序。

要让 Python 3 字典使用 Python 2 排序没有简单的方法,因此移动 2 和 3 代码库以使用 OrderedDict 是一种更易于维护的解决方案。

【讨论】:

  • 我无法更改在 Python 2 上生成的 MD5。有什么方法可以在 Python 3 上重现 Python 2 的默认顺序?
  • @MarceloSoares 没有简单/简单的方法可以做到这一点。我更新了答案以解决可能的解决方案
  • @EdwardMinnix 当你说没有琐碎的方法时......这可能吗? :\
猜你喜欢
  • 2023-01-16
  • 2021-07-08
  • 2011-12-19
  • 2019-01-09
  • 1970-01-01
  • 2015-10-11
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多