我正在使用Python 2从ASCII编码的文本文件解析JSON。
当使用^{
是否可以获取字符串对象而不是Unicode对象?
>>> import json
>>> original_list = ['a', 'b']
>>> json_list = json.dumps(original_list)
>>> json_list
'["a", "b"]'
>>> new_list = json.loads(json_list)
>>> new_list
[u'a', u'b'] # I want these to be of type `str`, not `unicode`
这个问题很久以前就被问到了,当时我正忙于使用Python 2。今天一个简单而干净的解决方案是使用最新版本的Python,即Python 3并转发。
虽然这里有一些好的答案,但我最终使用PyYAML来解析我的JSON文件,因为它将键和值指定为
str
类型字符串,而不是unicode
类型。因为JSON是YAML的一个子集,所以它工作得很好:注释
不过,需要注意的是:
我得到字符串对象,因为我的所有条目都是用ASCII编码的。如果我使用unicode编码的条目,我会将它们作为unicode对象返回-没有转换!
您应该(可能总是)使用PyYAML的
safe_load
函数;如果您使用它来加载JSON文件,那么无论如何,您不需要load
函数的“额外功能”。如果您想要一个对规范的1.2版本有更多支持的YAML解析器(和correctly parses very low numbers),请尝试Ruamel YAML:
pip install ruamel.yaml
并且import ruamel.yaml as yaml
是我在测试中所需要的全部。转换
如前所述,没有转换!如果不能确定只处理ASCII值(而且大多数情况下不能确定),最好使用转换函数:
我已经用过Mark Amery中的一个了好几次,它工作得很好,而且很容易使用。您还可以使用类似于
object_hook
的函数,因为它可能会提高大文件的性能。请参阅稍有涉及的answer from Mirec Miskuf。具有
的解object_hook
示例用法:
这个怎么用?我为什么要用它?
Mark Amery's function比这些短而清晰,那么它们有什么意义呢?你为什么要用它们?
纯粹用于性能。Mark的答案首先使用unicode字符串对JSON文本进行完全解码,然后通过整个解码值递归,将所有字符串转换为字节字符串。这有两个不良影响:
这个答案通过使用
json.load
和json.loads
的object_hook
参数缓解了这两个性能问题。来自the docs:由于词典在其他词典中嵌套了许多深层次,当它们被解码时会传递给
object_hook
,因此我们可以在此时指定其中的任何字符串或列表,避免以后需要深层递归。Mark的答案不适合作为
object_hook
使用,因为它递归到嵌套字典中。我们用_byteify
的ignore_dicts
参数防止这个答案中的递归,除了object_hook
向byteify传递一个新的dict
时的之外,这个参数始终传递给它。ignore_dicts
标志告诉_byteify
忽略dict
,因为它们已经被指定了。最后,我们的
json_load_byteified
和json_loads_byteified
实现对json.load
或json.loads
返回的结果调用_byteify
(使用ignore_dicts=True
),以处理正在解码的JSON文本在顶层没有dict
的情况。没有使json模块函数返回字节字符串而不是unicode字符串的内置选项。但是,这个简短的递归函数将任何解码的JSON对象从使用unicode字符串转换为UTF-8编码的字节字符串:
只需在从
json.load
或json.loads
调用获得的输出上调用此函数。几条注释:
return {byteify(key): byteify(value) for key, value in input.iteritems()}
替换为return dict([(byteify(key), byteify(value)) for key, value in input.iteritems()])
,因为直到Python2.7才支持字典理解。object_hook
或object_pairs_hook
参数来避免。Mirec Miskuf's answer是目前为止唯一一个能够正确实现这一点的方法,尽管结果是,它比我的方法要复杂得多。相关问题 更多 >
编程相关推荐