默认讨论Python3.6。一、计算机编码的发展1.1编码的诞生计算机的存储和计算都是以二进制形式进行的;因此,对于逻辑符号Char(数字、字母、汉字、数学字符、制表符等其他字符)需要有相应的二进制编码表示,这就是编码的作用。编码有两个方面,一个是字符集,一个是字符集对应的编码规则/算法。一般来说,人们认为Unicode编码是一种字符集,utf-8和utf-16是特定的字符编码规则/算法。但是如果想把unicode当成一种编码规则,也是可以的。如果有n个字符,可以用十进制n的二进制形式来表示这个字符集。这是最早的ascii码。但是unicode作为通用码需要满足的一些特性很难做到:1.向下兼容,2.易于扩展,3.兼顾存储和传输性能。1.2ASCIIASCII(AmericanStandardCodeforInformationInterchange,美国信息交换标准代码)是一种以拉丁字母为基础的计算机编码系统,主要用于显示现代英语和其他西欧语言。它是当今最常用的单字节编码系统,等同于国际标准ISO/IEC646。标准ASCII使用7个二进制位对字符进行编码。基本ASCII字符集共有128个字符,其中可打印字符96个,包括常用的字母、数字、标点符号等,控制字符32个。0到31代表回车、退格、删除等控制字符;32至126代表可通过键盘输入并显示的打印字符。!在ASCII中,字符集(charset)编码等同于编码方案。UNICODE中的字符集(charset)编码并不等同于编码方案。1.2.1ISO-8859-1(latin1)ASCII只能表示128个字符,显示不能完全表达,所以ISO-8859-1(latin-1)扩展了ASCII码,在ASCII码之上增加了包含西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号,并向后兼容ASCII编码。1.3ANSIASCII是由美国国家标准协会(ANSI)制定的,是一种用于基于文本的数据的标准单字节字符编码方案;ascii是ansi标准,包含128个字符(7位)。但是,我们常说的ANSI码,在windows平台上通常是指基于ANSI标准的ASCII扩展码。它将ASCII码扩展为8bits,从0x80-0xff增加了128个字符。ANSI码与ASCII码只有前126位相同。在简体中文Windows操作系统中,ANSI码代表GBK码在英文Windows操作系统中,ANSI码代表ASCII码在繁体中文Windows操作系统中,ANSI码代表Big5在日文中Windows操作系统,ANSI码表示Shift_JIS码1.3.1GB2312>GBK>GB18030GBK,全称ChineseInternalCodeSpecification,即中文内码扩展规范,1995年制定[gb2312即1980]。主要是对GB2312进行了扩充,在其基础上增加了更多的汉字。共收录汉字21003个。GBK向下兼容GB2312编码,也就是说GB2312编码的汉字用GBK可以正常解码,不会出现乱码,而GB2编码的汉字不能用GB2312解码。GB18030的全称是汉字内码扩展规范。它是2000年发布、2001年实施的最新内码字集,收录了中国大部分少数民族的文字,收录了7万多个汉字。主要采用单字节、双字节、四字节字符编码,向下兼容GB2312和GBK。虽然在我国是强制性标准,但在实际生产中很少使用,使用最多。相反,它是GBK和GB2312。1.4Unicode为了本国语言在计算机上的正常显示,每个国家和地区都有自己的编码,编码多了就不知道对方的编码了。这时,ISO组织提出了一种新的编码,称为UNICODE编码,可以支持全球的文化、字符和符号。UNICODE制定的时候,计算机容量已经不是问题,所以设计成固定两个字节,所有的字符都用16位来表示,包括以前只占8位的英文字符,这样会造成空间的浪费.长期没有得到推广应用。UNICODE可以理解为一种字符集映射方案;基于这种方案,也可以直接进行二进制编码(比如utf-16实现),但是效率会比较低,所以产生了utf-8实现。1.4.1UTF-16UTF-16是UNICODE的具体实现,16就是16位,UTF-16就是这么来的,它定义了UNICODE字符在计算机中的存储方式,UTF-16也是用两个字节来代表任意字符,这使得操作字符串非常高效,这也是java使用UTF-16作为内存中存储字符的格式的重要原因。1.4.2UTF-8UTF-16虽然效率很高,但也是UNICODE最大的缺点,让所有的单字节字符都要占用两个字节,存储空间翻倍,显然很耗资源,不符合当前的要求。互联网飞速发展的现状。于是就有了UTF-8,它是UNICODE的变长字符编码实现。它可以使用1到6个固定长度的字节来编码UNICODE字符。UTF-8对ASCII字符采用单字节存储,单个字符损坏不会影响后面的字符,所以UTF-8非常适合在网络上传输,也是使用最广泛的编码之一.如果要表示中文,UTF-8的编码效率大于GBK,小于UTF-16,所以也是GBK之外最理想的编码方式。UTF-16适合在磁盘和内存之间使用,字符和字节之间的转换会更简单高效,但不适合网络传输,因为网络传输可能会损坏字节流。2.Python3编解码系统2.1bytes和strPython3严格区分了str和bytes两种类型。Python3不会以任何隐式方式混合str和bytes。因此,用户不能拼接字符串和字节包,不能在字节包中查找字符串(反之亦然),不能将字符串传递给参数为字节包的函数(反之亦然)。>>>client.send("teststr")回溯(最近调用最后一次):文件“”,第1行,在类型错误:需要类似字节的对象,而不是“str”>>>>client.send(b"teststr")#将参数转换成bytestype8#返回发送数据的长度以text为例,Python在工作时会将text数据读入内存并解码成unicode编码,如前所述,unicode编码的UTF-16实现非常适合在内存中使用,因为它在操作字符串时非常高效。从用户的角度来看,这些编码为un??icode的解码字符在Python中是str。在内存中计算完成后,将文本数据写回磁盘,需要将数据编码成utf-8(一般使用utf-8,其他也可以)。从用户的角度来看,这些编码为utf-8的字符在Python中是字节。>>>b=bytes('Chinese','utf-8')>>>bb'\\xe4\\xb8\\xad\\xe6\\x96\\x87'>>>b.decode('Windows1252')'??\\xad?–?'>>>b.decode('ISO8859-7')'δε\\xadζ\\x96\\x87'>>>string=b.decode('utf-8')>>>string'中文'>>>b=string.encode('utf-8')>>>bb'\\xe4\\xb8\\xad\\xe6\\x96\\x87'2.2编解码工作流程我们可以把Python工作空间看成一个池子,一个入口负责将从硬盘读取的内容转换成unicode到内存中进行计算处理,一个出口负责将内存中的数据进行转换以utf-8或其他编码格式保存到硬盘。2.3Python常见编码解码错误及解决方法2.3.1读取数据时普遍出现非ASCII字符。原因是系统默认的编码类型与文件保存时的编码类型不一致。2.3.1.1查看系统编码类型:sys.getdefaultencoding()'utf-8'2.3.1.2查看文件编码类型:用vim打开文件,切换到最下面一行命令模式,在最下面输入以下命令line::setfileencodingfileencoding=utf除了-16le,还有基于文件规范和enca规范的方法。2.3.1.3实现匹配,一个方向是在Python读取文件的过程中指定与要读取的文件相同的编码方式,另一个方向是将要读取的文件转换成utf-8。哪个更有效就做什么。2.3.2UnicodeEncodeError一般出现在数据输出中,例如在打印过程中可能会出现:UnicodeEncodeError:'ascii'codeccan'tencodecharacter'\\U0001f621'inpos。2.3.2.1标准输出错误标准输出在Python中是print();调用print方法后,会将要打印的str按照默认的编码方式从unicode转换成对应的code交给操作系统,最后输出到显示器上。以下命令可以查询默认的标准输出编码方式:>>>importsys>>>sys.stdout.encoding'ANSI\_X3.4-1968''ANSI_X3.4-1968'只能支持标准ascii码字符输出,那么如何修改默认的标准输出编码标准来支持更多的输出字符呢?1.修改环境变量exportPYTHONIOENCODING=utf-82。有时你可能不想每次运行脚本时都改变环境变量,所以直接在脚本前指定。PYTHONIOENCODING=utf-8python代码.py3。修改代码中的importcodecssys.stdout=codecs.getwriter("utf-8")(sys.stdout.detach())sys.stdout.write("Yourcontent....")4.操作系统设置更改系统默认的语言编码设置,使标签输出默认为utf-8。最简单的处理方法如下。此方法可能不支持中文,但范围必须大于ASCII码。LC_ALL=C.UTF-82.3.2.2写入错误有时在写入文本文件或数据库时,也会出现编码错误(例如使用默认的ASCII码对汉字进行编码),解决方法一般是指定编码方式用于写作。#指定将str编码成bytes的标准是utf-8(也是默认的)withopen('test.txt','w',encoding='utf8')asf:f.write('something')#'wb'模式只能直接写入bytes类型withopen('test.txt','wb')asf:f.write('something'.encode('utf-8'))4.关联的软硬件编解码问题在实际开发过程中,仅仅了解Python的编解码模型是不够的。还需要更宏观的理解,比如Python和操作系统的编解码关系,Python和其他软件组件的编解码关系。4.1数据库编解码数据库一般有客户端和服务器。比如项目在A机上开发,数据库部署在B机上,那么A机上的sqlclient就是client,B机上的sqlserver就是server;机器A需要通过网络与机器B的数据库进行远程交互,完成数据的读写。在A机上,统一使用utf-8从B机的sqlserver读写文件就没有问题;但是如果你想在机器B本地读取数据,你可能需要设置读取的编码类型为utf-8。8、否则可能会出现读取乱码的问题。4.2操作系统LANG和locale程序运行使用一套语言需要字符集(数据)和字体(显示)。Locale是根据计算机用户使用的语言、所在的国家或地区以及当地的文化传统定义的软件运行时的locale。在locale环境中,有一组变量代表国际环境中的不同设置;其中一个叫LC_CTYPE,用于字符分类和字符串处理,控制所有字符如何处理,包括字符编码,字符是单字节还是多字节,如何打印等等,是最重要的环境多变的。如果在开发过程中遇到编码问题,还需要考虑操作系统本身的语言环境。详情参考https://www.cnblogs.com/rusking/p/3695993.html4.3建议4.3.1编码规范化为了保证后台进程编解码的顺利进行,最好是编码系统环境,文本编辑器,文件编码和数据库编码设置相同。4.3.2确保代码源文件使用Python2编码。py文件的默认编码是ASCII。在源代码文件中,如果使用非ASCII字符,需要在文件头中进行编码声明;Python3默认源文件编码为utf-8。5.REFERENCE1。架构师必须掌握的各种编码https://blog.csdn.net/moakun/article/details/801785902。PYTHON编解码https://blog.csdn.net/can0227/article/details/832407053。Linux查看文件编码格式https://blog.csdn.net/mayue_web/article/details/89404395