如何在Python (2.6)中将JSON解码为字符串而非Unicode?

9 投票
2 回答
9498 浏览
提问于 2025-04-16 10:11

我有一个配置文件,格式是JSON,里面包含了一些字符串变量(都是ASCII字符)。这些字符串默认会被解码成Unicode格式,但因为我需要把这些变量传递给我的Python C扩展,所以我需要它们作为普通的Python字符串。目前我使用str(unicode)来转换这些JSON字符串,但我希望能有一个更优雅、更简洁的解决方案。

有没有办法通过自定义的JSONDecoder或者对象钩子来改变默认的字符串到Unicode的转换?

2 个回答

0

看看对这个问题的回答是否对你有帮助(在那个问题中,提问者使用的是simplejson)。

1

如果你不想牺牲一些速度,那就不行。如果你能接受速度稍微慢一点的话,你需要考虑使用普通的 json.loads 方法,然后递归地转换成 str 可能会更便宜,甚至可能更快。

说到这里,如果你真的想要一个返回字符串的 loads 方法,愿意接受一些原本不该用的扩展代码,那这里有一个可能的结果(大部分是通过复制粘贴扩展的)

这真是太傻了,感谢Lennart让我看清了真相(也就是说,你只需要扩展 JSONDecoder 和一些小技巧):

import json
from json import decoder, scanner

from json.scanner import make_scanner
from _json import scanstring as c_scanstring

_CONSTANTS = json.decoder._CONSTANTS

py_make_scanner = scanner.py_make_scanner

# Convert from unicode to str
def str_scanstring(*args, **kwargs):
    result = c_scanstring(*args, **kwargs)
    return str(result[0]), result[1]

# Little dirty trick here
json.decoder.scanstring = str_scanstring

class StrJSONDecoder(decoder.JSONDecoder):
    def __init__(self, encoding=None, object_hook=None, parse_float=None,
            parse_int=None, parse_constant=None, strict=True,
            object_pairs_hook=None):
        self.encoding = encoding
        self.object_hook = object_hook
        self.object_pairs_hook = object_pairs_hook
        self.parse_float = parse_float or float
        self.parse_int = parse_int or int
        self.parse_constant = parse_constant or _CONSTANTS.__getitem__
        self.strict = strict
        self.parse_object = decoder.JSONObject
        self.parse_array = decoder.JSONArray
        self.parse_string = str_scanstring
        self.scan_once = py_make_scanner(self)

# And another little dirty trick there    
_default_decoder = StrJSONDecoder(encoding=None, object_hook=None,
                               object_pairs_hook=None)

json._default_decoder = _default_decoder

j = {1:'2', 1.1:[1,2,3], u'test': {12:12, 13:'o'}}
print json.loads(json.dumps(j))

撰写回答