Python强制dict条目为utf-8

Python强制dict条目为utf-8,python,unicode,utf-8,dictionary,Python,Unicode,Utf 8,Dictionary,我花了一个下午的大部分时间尝试将字典对象修补为utf-8编码而不是unicode。我试图找到扩展dictionary对象的最快、性能最好的方法,并确保它的条目、键和值都是utf-8 这是我提出的,它确实起作用,但我想知道可以做些什么改进 class UTF8Dict(dict): def __init__(self, *args, **kwargs): d = dict(*args, **kwargs) d = _decode_dict(d)

我花了一个下午的大部分时间尝试将字典对象修补为utf-8编码而不是unicode。我试图找到扩展dictionary对象的最快、性能最好的方法,并确保它的条目、键和值都是utf-8

这是我提出的,它确实起作用,但我想知道可以做些什么改进

class UTF8Dict(dict):
    def __init__(self, *args, **kwargs):
        d = dict(*args, **kwargs)
        d = _decode_dict(d)
        super(UTF8Dict,self).__init__(d)
    def __setitem__(self,key,value):
        if isinstance(key,unicode):
            key = key.encode('utf-8')
        if isinstance(value,unicode):
            value = value.encode('utf-8')
        return super(UTF8Dict,self).__setitem__(key,value)

def _decode_list(data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        elif isinstance(item, list):
            item = _decode_list(item)
        elif isinstance(item, dict):
            item = _decode_dict(item)
        rv.append(item)
    return rv

def _decode_dict(data):
    rv = {}
    for key, value in data.iteritems():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        elif isinstance(value, list):
            value = _decode_list(value)
        elif isinstance(value, dict):
            value = _decode_dict(value)
        rv[key] = value
    return rv
改进以下任何一项的建议都非常有用:

  • 演出
  • 覆盖更多边缘案例
  • 错误处理

    • 我同意有评论说这可能是误导。也就是说,您当前的计划中存在一些漏洞:

    • d.setdefault
      可用于将unicode对象添加到dict:

      >>> d = UTF8Dict()
      >>> d.setdefault(u'x', u'y')
      
      >>> d = UTF8Dict()
      >>> d.update({u'x': u'y'})
      
    • d.update
      可用于将unicode对象添加到dict:

      >>> d = UTF8Dict()
      >>> d.setdefault(u'x', u'y')
      
      >>> d = UTF8Dict()
      >>> d.update({u'x': u'y'})
      
    • 可以使用任何标准列表操作修改dict中包含的列表值以包括unicode对象。例如:

      >>> d = UTF8Dict(x=[])
      >>> d['x'].append(u'x')
      

    • 为什么要确保数据结构只包含utf-8字符串?

      为什么要这样做?只需将键/值存储为unicode对象,然后根据需要进行编码。扩展中最需要的是isinstance检查,如果它失败,将引发异常。最佳做法是在代码的输入和输出边缘进行编码和解码(因此,在接收时立即解码,在发送时尽可能晚进行编码),并在内部保持unicode。为什么要强制执行任何操作?只需制作一个字典,只添加具有正确编码的键/值。试图强制类型和编码不是Pythonic,而是“UTF-8而不是Unicode”。说什么?@tchrist:Python对“str”(字节字符串)和“unicode”(unicode代码点序列)有不同的类型。UTF-8是Unicode的一种特殊编码;它指定字节字符串中的字节应该是什么。在Python解释器中自己尝试一下:
      s=u'résumé';st=s.encode('utf8');t。OP需要字节字符串(以UTF-8编码),而不是Unicode字符串(无论是UTF-8还是UTF-16或其他编码方式,Unicode字符串都是不可知的)。此连接到的端点仅处理utf-8。如果类型是str:hate_my_life()
      ,那么它们的确切代码就是这个
      ,这就是我修补所有这些的原因。我让他们把它改成
      isinstance(s,basestring)
      ,但是“我们还没有准备好使用unicode”还没有完全弄明白这一点。@lukecampbell编写一个函数,将dict作为其输入,遍历dict(以及您关心的任何子结构),并对任何unicode字符串进行编码,是否可行?然后,您可以在使用外部“端点”代码之前调用此函数,该代码在其输入dict中需要utf-8。我最初使用了该方法,因此在对象定义下使用了两个函数,但从dict扩展的基础端点现在将扩展此对象,从而强制遵守utf-8。我不能强制执行客户在处理dicts时使用utf-8的策略。。如果类型为str,你能用猴子修补正在执行的邪恶模块吗?例如,将一个
      类型
      函数注入到其名称空间中,类似于:
      if isinstance(s,basestring):return str;其他:返回内置类型
      ?我承认不太干净。:)实际上,我只是干脆把它改成了
      isinstance(s,basestring)
      ,但后来收到一封电子邮件,基本上是这样写的:“不要碰它不在你的域中”,接下来是一条长长的电子邮件链,我试图推动unicode支持,这在Python中并不难。