Python-2020-fall-python character set
跳到导航
跳到搜索
python汉字编码
- Unicode:
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000至0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个。然而目前只用了少数平面。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。 所以Unicode 是「字符集」,UTF-8 是「编码规则」。 参考资料: 百度百科:https://baike.baidu.com/item/Unicode/750500?fr=aladdin 知乎邱昊宇:https://www.zhihu.com/question/23374078
- UTF-8:
UTF-8 顾名思义,是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节。 表: 格式 所占字节数 0XXX XXXX 1 110X XXXX 10XX XXXX 2 1110 XXXX 10XX XXXX 10XX XXXX 3 1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX 4 1111 10XX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX 5 1111 110X 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX 6 所以,根据UTF-8的编码格式,UTF-8编码字符理论上可以最多到6个字节长,然而字节0xFE和OxFF在UTF-8编码中从未用到。 参考资料: 百度百科:https://baike.baidu.com/item/UTF-8/481798?fr=aladdin
- UTF-16,UTF-32:
UTF-16: 把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。 UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节(2字节)储存,但UTF-16却无法兼容于ASCII编码。 UTF-32: UTF-32是一种固定宽度(也称为等宽、等长或定长)码元序列的Unicode字符编码方式。 空间效率低下,连ASCII码都占4个字节,且其优势相对UTF-8和UTF-16不明显。 百度百科: UTF-16:https://baike.baidu.com/item/UTF-16/9032026?fr=aladdin#2 UTF-32:https://baike.baidu.com/item/UTF-32/734460?fr=aladdin 详细编码剖析,知乎笨笨阿林: UTF-16:https://zhuanlan.zhihu.com/p/27827951 UTF-32:https://zhuanlan.zhihu.com/p/86859029
- python字符集:
先看代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注释是告诉linux系统,windows系统会忽略该行注释
第二行注释是告诉python解释器按照UTF-8编码读取源码,否则可能会出现乱码
这个指定的是,你用于存储python代码的.py格式文件的文本存储方式。我们程序本身,依然是使用unicode编码格式(默认编码就是unicode,我测试都是utf-8,这里可能会和编辑器有关),与文件格式无关。
请看代码:
# /usr/bin/env python
# -*- coding: gbk -*-
import sys
print("系统默认编码是:", sys.getdefaultencoding())
此时输出:系统默认编码是: utf-8
encode方法:是str类型对象的一个方法。可以将str类型的字符串,编码成指定的二进制格式。
请看代码:
msg = '世界你好'
msg_utf8 = msg.encode('utf-8')
print(msg)
print(msg_utf8)
print(type(msg_utf8))
print(msg_utf8.decode('utf-8'))
此时输出:
世界你好
b'\xe4\xb8\x96\xe7\x95\x8c\xe4\xbd\xa0\xe5\xa5\xbd'
<class 'bytes'>
世界你好
decode方法:str形式的字符串是没有decode方法的。decode方法是bytes类型特有的。此方法会把bytes类型的二进制串,解码成指定格式的字符串。
我们再举一个极端的例子:
请看代码:
msg = '''很久很久以前有个漂亮的公主,她被恶龙抓走了,勇敢的王子为了拯救公主,拿着宝剑,骑着白马踏上征程。
王子不断地打怪升级,最终见到了恶龙,王子问:
“恶龙,报上名来,吾乃达拉崩吧斑得贝迪卜多比鲁翁,我的宝剑不斩无名之辈!”
恶龙:“哇哈哈哈,口气还不小,我是昆图库塔卡提考特苏瓦西拉松,让你知道我的厉害”'''
msg_utf8 = msg.encode('utf-8')
print(msg_utf8)
此时输出:
b'\xe5\xbe\x88\xe4\xb9\x85\xe5\xbe\x88\xe4\xb9\x85\xe4\xbb\xa5\xe5\x89\x8d\xe6\x9c\x89\xe4\xb8\xaa\xe6\xbc\x82\xe4\xba\xae\xe7\x9a\x84\xe5\x85\xac\xe4\xb8\xbb\xef\xbc\x8c\xe5\xa5\xb9\xe8
\xa2\xab\xe6\x81\xb6\xe9\xbe\x99\xe6\x8a\x93\xe8\xb5\xb0\xe4\xba\x86\xef\xbc\x8c\xe5\x8b\x87\xe6\x95\xa2\xe7\x9a\x84\xe7\x8e\x8b\xe5\xad\x90\xe4\xb8\xba\xe4\xba\x86\xe6\x8b\xaf\xe6\x95\x91
\xe5\x85\xac\xe4\xb8\xbb\xef\xbc\x8c\xe6\x8b\xbf\xe7\x9d\x80\xe5\xae\x9d\xe5\x89\x91\xef\xbc\x8c\xe9\xaa\x91\xe7\x9d\x80\xe7\x99\xbd\xe9\xa9\xac\xe8\xb8\x8f\xe4\xb8\x8a\xe5\xbe\x81\xe7\xa8
\x8b\xe3\x80\x82\n\xe7\x8e\x8b\xe5\xad\x90\xe4\xb8\x8d\xe6\x96\xad\xe5\x9c\xb0\xe6\x89\x93\xe6\x80\xaa\xe5\x8d\x87\xe7\xba\xa7\xef\xbc\x8c\xe6\x9c\x80\xe7\xbb\x88\xe8\xa7\x81\xe5\x88\xb0
\xe4\xba\x86\xe6\x81\xb6\xe9\xbe\x99\xef\xbc\x8c\xe7\x8e\x8b\xe5\xad\x90\xe9\x97\xae\xef\xbc\x9a\n\xe2\x80\x9c\xe6\x81\xb6\xe9\xbe\x99\xef\xbc\x8c\xe6\x8a\xa5\xe4\xb8\x8a\xe5\x90\x8d\xe6
\x9d\xa5\xef\xbc\x8c\xe5\x90\xbe\xe4\xb9\x83\xe8\xbe\xbe\xe6\x8b\x89\xe5\xb4\xa9\xe5\x90\xa7\xe6\x96\x91\xe5\xbe\x97\xe8\xb4\x9d\xe8\xbf\xaa\xe5\x8d\x9c\xe5\xa4\x9a\xe6\xaf\x94\xe9\xb2\x81
\xe7\xbf\x81\xef\xbc\x8c\xe6\x88\x91\xe7\x9a\x84\xe5\xae\x9d\xe5\x89\x91\xe4\xb8\x8d\xe6\x96\xa9\xe6\x97\xa0\xe5\x90\x8d\xe4\xb9\x8b\xe8\xbe\x88\xef\xbc\x81\xe2\x80\x9d\n\xe6\x81\xb6\xe9
\xbe\x99\xef\xbc\x9a\xe2\x80\x9c\xe5\x93\x87\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88\xef\xbc\x8c\xe5\x8f\xa3\xe6\xb0\x94\xe8\xbf\x98\xe4\xb8\x8d\xe5\xb0\x8f\xef\xbc\x8c\xe6\x88\x91\xe6\x98\xaf
\xe6\x98\x86\xe5\x9b\xbe\xe5\xba\x93\xe5\xa1\x94\xe5\x8d\xa1\xe6\x8f\x90\xe8\x80\x83\xe7\x89\xb9\xe8\x8b\x8f\xe7\x93\xa6\xe8\xa5\xbf\xe6\x8b\x89\xe6\x9d\xbe\xef\xbc\x8c\xe8\xae\xa9\xe4\xbd
\xa0\xe7\x9f\xa5\xe9\x81\x93\xe6\x88\x91\xe7\x9a\x84\xe5\x8e\x89\xe5\xae\xb3\xe2\x80\x9d'
不难看出:\x是一个16进制的转义字符,\x后面跟的1-9和a-f都是对应的半个字节的数(二进制的4个位等同于16进制的1个位),所以一个\x后面跟着的是一个字节。
我们的二进制串和字符串有很多相像的地方。甚至在二进制串中,仍然出现了\n这样的转义字符,但是我自己测试,b''里面包含转义字符和ascii字符以外的字符就会报错,这说明这个b操作,会自动把字符串编码成二进制串,这里应该有个隐式过程。
总结:
我们的代码字符编码和默认python的运行环境无关。
python默认的字符集使用unicode,我本人测试是utf-8(可能不同的IDE或者解释器会不一样的,Python2和Python3就不一样)。str就是在用这个默认字符集来存储和解码,这里有一个python隐式过程。
encode和decode分别是str和types的方法。
我们有两种不一样的type来保存str和bytes,bytes应该就是python隐式再编码str得来的,str就是单纯用引号括起来,而bytes是在用引号包裹的二进制数中前面加b,即b''。
参考资料:
博客博主“不懂ABAP的python不是好basis”:https://www.cnblogs.com/jenvid/p/7826144.html
博客博主“默默前行的蜗牛”:https://blog.csdn.net/ywf008/article/details/90053864