编码问题
【背景】
- 计算机只能处理数字,文字转换为数字才能处理
- 计算机中8bit作为一个字节,所以一个字节能表示最大的数字就是255
常用编码 | 说明 | 问题及其他 |
---|---|---|
ASCII | 一个字节可以表示完26个字母->ASCII(一个字节)编码就成为美国人的标准编码 | ASCII用于中文明显不够,中文不止255个汉字 |
GB2312 | 用两个字节表示一个汉字 | 日文、韩文等上百种国家为了解决这个问题都发展了一套字节的编码,标准就越来越多,如果出现多种语言混合显示就一定会出现乱码 |
unicode | 将所有语言统一到一套编码里 | 如果内容全是英文,unicode编码比ASCII需要多一倍的存储空间,传输叶需要多一倍的空间 常用语Python内存中 |
utf-8 | 把英文变长成1个字节,汉字用3个字节。特别生僻的变成4-6字节 | 常用于文件保存和传输,进行空间压缩 |
【ASCII和unicode编码】
- 字母A用ASCII编码十进制是65,二进制是 0100 0001
- 汉字“中”已近超出了ASCII编码的范围,用unicode编码是20013,二进制是 01001110 00101101
- A用unicode编码只需要前面补0:00000000 0100 0001(浪费了很多空间)–>提出了utf-8编码
Python编程
原理
【Python中的编码】
- Python在内存中使用unicode编码
s = "我用Python"
在windows下是GB2312编码,linux下是utf8
【windows环境】
# 英文测试 - 没有问题
>>> s = "abc" #windows下为gb2312
>>> su = u"abc" #unicode,在Python3中已经把所有的字符串都处理为unicode
>>> s.encode("utf8")
'abc'
>>> su.encode("utf8")
'abc'
# 中文测试
>>> s = "我用Python" #windows下为gb2312
>>> su = u"我用Python" #unicode,在Python3中已经把所有的字符串都处理为unicode
>>> s.encode("utf8")
UnicodeDecodeError:'utf8' codec can't decode byte 0xce in position 0: invalid continuation byte
# 在使用encode()函数之前必须确保s是一个unicode的编码
# 1. 先要将字符串转成unicode的编码:`s.decode("gb2312")`
# 2. 然后再将s转成utf8编码:`s.decode("gb2312").encode("utf8")`
>>> su.encode("utf-8")
# su已经是一个unicode就不会报错
【linux环境】
# linux环境
>>> s = "我用Python"
>>> import sys
>>> sys.getdefaultencoding() #查看默认编码
'ascii'
>>> s.encode("utf8")
# 执行时默认为:s.decode("ascii").encode("utf8")
# 但在linux下是utf8,所以s.decode("ascii")就已经出错