我见过许多项目使用simplejson模块而不是标准库中的json模块。此外,还有许多不同的simplejson模块。为什么要使用这些替代品,而不是标准库中的替代品?


当前回答

在python3中,如果你有一个b'bytes'的字符串,使用json你必须在加载它之前解码()内容。Simplejson会处理这个问题,所以你可以只做Simplejson .loads(byte_string)。

其他回答

项目使用simplejson的另一个原因是内置json最初不包括它的C加速,所以性能差异是显而易见的。

内置json模块被包含在Python 2.6中。任何支持Python < 2.6版本的项目都需要有一个备份。在很多情况下,这种退路很简单。

在最新版本中,Json在加载和转储两种情况下都比simplejson快

测试版本:

python: 3.6.8 json: 2.0.9 simplejson: 3.16.0

结果:

>>> def test(obj, call, data, times):
...   s = datetime.now()
...   print("calling: ", call, " in ", obj, " ", times, " times") 
...   for _ in range(times):
...     r = getattr(obj, call)(data)
...   e = datetime.now()
...   print("total time: ", str(e-s))
...   return r

>>> test(json, "dumps", data, 10000)
calling:  dumps  in  <module 'json' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\json\\__init__.py'>   10000  times
total time:  0:00:00.054857

>>> test(simplejson, "dumps", data, 10000)
calling:  dumps  in  <module 'simplejson' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\simplejson\\__init__.py'>   10000  times
total time:  0:00:00.419895
'{"1": 100, "2": "acs", "3.5": 3.5567, "d": [1, "23"], "e": {"a": "A"}}'

>>> test(json, "loads", strdata, 1000)
calling:  loads  in  <module 'json' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\json\\__init__.py'>   1000  times
total time:  0:00:00.004985
{'1': 100, '2': 'acs', '3.5': 3.5567, 'd': [1, '23'], 'e': {'a': 'A'}}

>>> test(simplejson, "loads", strdata, 1000)
calling:  loads  in  <module 'simplejson' from 'C:\\Users\\jophine.antony\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\simplejson\\__init__.py'>   1000  times
total time:  0:00:00.040890
{'1': 100, '2': 'acs', '3.5': 3.5567, 'd': [1, '23'], 'e': {'a': 'A'}}

版本:

python: 3.7.4 json: 2.0.9 simplejson: 3.17.0

Json在转储操作中比simplejson快,但在加载操作中两者保持相同的速度

一些值在simplejson和json之间的序列化方式不同。

值得注意的是,collections.namedtuple的实例被json序列化为数组,而被simplejson序列化为对象。您可以通过将namedtuple_as_object=False传递给simplejson来覆盖此行为。转储,但默认情况下行为不匹配。

>>> import collections, simplejson, json
>>> TupleClass = collections.namedtuple("TupleClass", ("a", "b"))
>>> value = TupleClass(1, 2)
>>> json.dumps(value)
'[1, 2]'
>>> simplejson.dumps(value)
'{"a": 1, "b": 2}'
>>> simplejson.dumps(value, namedtuple_as_object=False)
'[1, 2]'

我发现Python 2.7与simplejson 3.3.1的API不兼容在于输出是生成str对象还是unicode对象。 如。

>>> from json import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{u'a': u'b'}

vs

>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode("""{ "a":"b" }""")
{'a': 'b'}

如果首选使用simplejson,则可以通过将参数字符串强制转换为unicode来解决,如下所示:

>>> from simplejson import JSONDecoder
>>> jd = JSONDecoder()
>>> jd.decode(unicode("""{ "a":"b" }""", "utf-8"))
{u'a': u'b'}

强制转换确实需要知道原始字符集,例如:

>>> jd.decode(unicode("""{ "a": "ξηθννββωφρες" }"""))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 8: ordinal not in range(128)

这是第40个问题