python3 字符编码
编码
为什么有编码
计算机只能处理数字,人类需要处理大量的文本,如果要计算机处理文本,就必须把文本转换为数字,才可以进行处理。
编码可以理解为编码表,每个字母或汉字对应一个二进制或十进制的编号。在将文本文档的文字(汉字、韩语、日文等等语言)转化为计算机可以理解的数字的时候,去表格里面找这些数字,方便计算机理解。比如:
字母A用ASCII编码是十进制的65,二进制的01000001
字符0用ASCII编码是十进制的48,二进制的00110000,
ASCII 编码
计算机是美国人发明的,所以,最早只有 127 个大小写字母、数字和一些符号进入了编码体系,这套编码就是 ASCII 码。比如:
大写字母 A 的编码是 65,小写字母 z 的编码是 122。
ASCII 编码的局限性是该编码只解决了将英语转化为计算机能理解的语言的问题,对于中文、日文、韩文、等等其他语言的转换,会出现乱码,为了解决乱码的国际问题,有了 Unicode 编码
Unicode 编码
Unicode 编码把所有语言都统一到一套编码里面,这样就不会有乱码的问题了。python3 内部使用的就是 unicode 编码
但是随之而来的新问题是,Unicode 编码比 ASCII 编码需要多一倍的存储空间(原理在此不阐述,我也不懂,有兴趣可以问问度娘),那么在存储和传输上面就不划算,为了解决这个问题,又将 Unicode 编码转化为 UTF-8 编码。
UTF-8 编码
因为解决了大部分语言编码的问题,又被称为万国码。
能将各个国家的各种语言随意转换。
GBK 编码
GBK全称《汉字内码扩展规范》,属于国家标准,
GBK 和 UTF-8 的主要区别:
GBK 包含全部中文字符
UTF-8 包含全世界所有国家需要用到的字符。
GBK是在国家标准GB2312基础上扩容后兼容GB2312的标准(我是没看懂,你们随意)
UTF-8编码的文字可以在各国各种支持UTF8字符集的浏览器上显示。
如果是UTF8编码,则在外国人的英文IE上也能显示中文,而无需他们下载IE的中文语言支持包。
所以,对于英文比较多的论坛 ,使用GBK则每个字符占用2个字节,而使用UTF-8英文却只占1个字节。
UTF8是国际编码,它的通用性比较好,外国人也可以浏览论坛,GBK是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大。
编码工作方式
计算机内存中,统一使用Unicode编码
,你在 .py 或者 .txt 键入文字的时候,计算机内存是以 Unicode 编码的方式对这些文字进行保存的。
编辑完成之后,保存的时候,再把 Unicode 编码转化为 UTF-8 保存的文件中。
另外流量网页的时候,服务器会把动态生成的 Unicode 内容,转化为 UTF-8 编码形式,再传输到浏览器,那么用户就可以看到自己能理解的语言组成的网页,比如中文、日文、韩文等等。很多网页的源代码上会有类似<meta charset='UTF-8' /> 的信息,表示该网页是 UTF-8 编码
python3 编码
python3 使用的是 Unicode 编码方式,也就意味着,python3 字符串支持多语言。
虽然 python3 字符串类型在内存中以 Unicode 表示,但是在网络上传输或者保存到磁盘的时候,需要把 str 变为以字节为单位的 bytes。
encode() 方法
encode 方法以指定的编码格式编码字符串。返回编码后的字符串,是一个 bytes 对象
。
str.encode(encoding='UTF-8',errors='strict')
- encoding: 需要使用的编码,如 UTF-8,GBK
- errors:可选参数,默认 strict,表示如果发生编码错误,返回一个 UnicodeError。
decode() 方法
decode 方法以指定的编码格式解码 bytes 对象,默认 UTF-8 编码,该方法返回解码后的字符串。
bytes.decode(encoding='UTF-8',errors='strict')
- encoding:要使用的编码,UTF-8,GBK
- error:可选参数,了解即可,默认 strict,可不写。
str = '阿铭python'
str_utf8 = str.encode('UTF-8')
str_gbk = str.encode('GBK')
print(str)
print('str 对象类型:', type(str))
print('\r')
print('UTF-8 编码:', str_utf8)
print('str_utf-8 对象类型:', type(str_utf8))
print('\r')
print('GBK 编码: ', str_gbk)
print('str_gbk 对象类型:', type(str_gbk))
print('\r')
print('UTF-8 解码:', str_utf8.decode('UTF-8', 'strict'))
print('GBK 解码: ', str_gbk.decode('GBK', 'strict'))
结果如下:
阿铭python
str 对象类型: <class 'str'>
UTF-8 编码: b'\xe9\x98\xbf\xe9\x93\xadpython'
str_utf-8 对象类型: <class 'bytes'>
GBK 编码: b'\xb0\xa2\xc3\xfapython'
str_gbk 对象类型: <class 'bytes'>
UTF-8 解码: 阿铭python
GBK 解码: 阿铭python
这些乱码有没有看起来很熟悉!!!!!!所以下次看到的时候,可以说这些不是乱码,是 UTF-8 和 GBK 编码的 bytes 对象。(我其实不知道我想表达什么 – -#)
python3 乱码
python3 内部使用 unicode 编码,外部面对各种各样乱七八糟的编码,中国最常用的是 gbk 和 utf-8。
在编辑 .py 的时候,python 默认会任务源代码文件是 ASCII 编码。如果代码只涉及的英文,那么转换没有问题,如果涉及到其他语言,比如中文,就会抛出异常。
解决方法很简单,在源码文件的前两行指定编码格式,网上有说一定放在前两行,放在第三行都不起作用。
# -*- coding: utf-8 -*-
window 问题
如果在 window 控制台运行代码,虽然程序执行了,但是屏幕上打印的不是中文,原因是 python 编码于控制台编码不一致。
Windows 控制台使用的是 gbk
,而代码中使用的 utf-8,编码和解码的方式不一致,那么就不能正常的显示。
解决方法是将源码文件修改为:
# -*- coding: gbk -*-
或者另外一种方式,保持源码文件 utf-8 格式不变,在中文字符串前面添加 u 字母,表示后面的字符串以 unicode 格式存储。
a = '大师兄'
b = u'大师兄'
print(a, type(a))
print(b, type(b))
字符前面加 u 表明这是一个 unicode 对象,这个字会以 unicode 格式存在于内存中,而如果不加u 表明这仅仅是一个使用某种编码的字符串,编码格式取决于 python 对源码文件编码的识别。
Python 在向控制台输出 unicode 对象的时候会自动根据输出环境的编码进行转换,但如果输出的不是 unicode 对象而是普通字符串,则会直接按照字符串的编码输出字符串,从而出现乱码的现象。
encode 和 decode 方法
decode函数也可以将一个普通字符串转换为unicode对象。
decode 将普通字符串按照参数中的编码格式进行解析,然后生成对应的 unicode 对象。
那么encode正好就是相反的功能,是将一个unicode对象转换为参数中编码格式的普通字符。
isinstance()
判断字符串是否是 unicode 的方法,python2 和 python3 略有不同,但是使用的都是 isinstance 方法。
# python2
isinstance(str, unicode)
# python3
isinstance(str, str)
另外补充一个获取系统默认编码的方法
import sys
print(sys.getdefaultencoding())