谈谈Python编码问题和Unicode

Download Report

Transcript 谈谈Python编码问题和Unicode

谈谈Python编码问题和Unicode
taochunhua@tencent
outline
•
•
•
•
Unicode基础知识
Python的str和unicode
Json编码工具
实例
Unicode
• Ascii时代
– 7位,最高位是校验位
• MBCS时代(多字节字符集)
– 中文CP963,GBK,GB2312,BIG5
• Unicode
– Unicode16,Unicode32
题外话:存在与表示
• Big Endian & Little Endian
– SPARK, x86, ARM
• Host Byte Order & Network Byte Order
– htonl, ntohl, htons, ntohs
• Object Persistence & Serialize
– MFC, java serialiable interface and
persistence api, protobuf
• Unicode & UTF, UCS
– Several mechanisms have been specified for
implementing Unicode.
unicode & utf
• unicode
– unicode16, unicode32
–
• Unicode Transformation Format (UTF)
– UTF16(Big/Little Endian)
– UTF32(Big/Little Endian)
– UTF8
• 变长方案
• 思考?为什么是变长的?如何实现?
Python str & unicode
• str对象
– 存储ascii字符串,以及二进制数据
• unicode对象
– 存储unicode字符串,采用的是utf16或utf32
• str用来存储各种utf数据,包括gbk等
• 可以认为:unicode对象是理想的unicode,
str是丑陋的现实(各种utf)
str与unicode的转化
str
decode
encode
unicode
使用时机
• 拇指定律
– IO时用str
• e.g. network, file read write
– 内部处理时用unicode
• json encode, string process
• 例子
1.从外部读入时它是str
2.转为unicode进行必要处理
3.再转为str输出
demo
• 体验demo.py
import json
• 我懂了上面说的,为什么json还是搞不定?
– 嗯,因为json帮你encode,decode了一些东西
• 需要仔细阅读json模块的文档
• json.dumps(obj, ensure_ascii,encoding...)
– obj python数据结构: dic, list ...
– ensure_ascii = True(default)
• dumps返回一个str
– ensure_ascii = False
• dumps返回一个unicode!我们可以进一步对它
encode
– encoding
• 在obj进行转化之前,所有obj中的str会转为unicode,
即str.decode(encoding)
– 默认情况:
• str -> unicode -> json(unicode) -> str
一个默认处理
• json.dumps(d, encoding='gbk')
– 它返回一个str
• str -> unicode -> json(unicode) -> str
– str->unicode的decode在 encoding参数控制
– json(unicode) -> str 这里的encoding是默认控
制的!
– 这个默认控制不是encode,而是直接把
unicode转义为ascii编码,这个ascii码的内容是
unicode!
– 这里应该是个utf8,这个过程是个硬编码:见lib
中encode.py
证据
• 老白干酒
– utf8 : 0x8001 0x767D 0x5E72 0x9152
– gbk : 0xC0CF 0xB0D7 0xB8C9 0xBEC6
JSON本身的规范和实现
• 有了以上知识,我们还有可能搞不定特定
需求:比如,请给我弄个GKB的字符串!
• JSON规范定义string必须是unicode字符串,
但是实现形式默认是utf8
• 有些json解析函数仅实现了utf8,不支持其
他格式!
实例
• 后台程序写入数据到redis
实例
• redis中数据
实例
• php接口