将JSON反序列化为unicode时出现Python问题

时间:2014-01-05 00:57:30

标签: python json unicode

我有一些Python代码使用工厂类方法将JSON解析为对象。

以下是一个这样的课程的例子:

class Rect(object):

    def __init__(self, x, y, width, height):
        self.x = int(x)
        self.y = int(y)
        self.width = int(width)
        self.height = int(height)       

    @classmethod
    def from_dict(cls, raw_dict):
        return cls(**raw_dict)

    @classmethod
    def from_json(cls, raw_json):

        d = json.loads(raw_json)
        return cls.from_dict(d)

当我将原始的,python序列化的JSON传递给类时,它工作正常,但如果我从Flask web请求传递JSON(例如来自Flask的request.json),我在类实例化时会收到错误:< / p>

  

TypeError: init ()关键字必须是字符串

那是因为我从Flask请求中返回的JSON都是unicode,显然cls(**raw_dict)无法理解unicode键。

换句话说,这有效:

Rect.from_dict({ "x": 0, "y": 0, "width": 100, "height": 100 })

但这不会:

Rect.from_dict({u'y': 0, u'width': 0, u'x': 0, u'height': 0})

所以我的问题实际上是两部分:

  1. 我应该如何解决这个问题?我应该尝试将所有传入的JSON格式unicode转换为字符串吗?或者我应该尝试以某种方式容纳unicode?
  2. 为什么这是一个问题? Python不应该能够自动将unicode消化为字符串吗?这个问题是否表现在像Ruby这样的语言中? (注意:this question的答案中,人们建议保留unicode因为这是JSON规范,但显然Python不允许使用unicode简单替换字符串 - 否则我的代码将起作用。)

  3. 更新

    此问题仅在Python&lt; = 2.6。

    中表现出来

1 个答案:

答案 0 :(得分:3)

JSON标准仅使用Unicode,因此json.loads()字典中的所有键始终为unicode值。

对于Python 2.6及更早版本,这些很容易编码:

d = dict((key.encode('ascii'), value) for (key, value) in json.loads(raw_json).iteritems())

因为Python 2标识符只能使用ASCII字符。在Python 2.7和更高版本中,unicode关键字会自动编码。

在Python 3中,标识符已经是unicode,这不是问题。