Python编码一直是许多Python开发人员的噩梦。一个烦人的编码问题,花了很长时间才弄明白。过了一段时间,我又忘记了这件事。一脸懵逼的你开始找各种博客和帖子,从头搞清楚什么是编码?什么是单码?它和ASCII码有什么区别?为什么decodeencode总是报错?为什么python2和python3中的字符串类型不一样?如何对应?如何检测编码格式?周而复始,这个过程真的很痛苦。今天给大家讲解了一些大家在Python上都会遇到的编码问题。以后不用谷歌就可以保存这篇文章。1.Python3中的str和bytes在Python3中,有两种类型的字符串,str和bytes。今天说说两者的区别:unicodestring(str类型):以Unicode码点的形式存储,人类识别的形式bytestring(bytes类型):以byte的形式存储,人类识别的形式machineinPython3你定义的所有字符串都是unicode字符串类型,可以通过type和isinstance区分:#python3>>>str_obj="Hello">>>>>>>type(str_obj)>>>>>>>isinstance("Hello",str)True>>>>>>isinstance("Hello",bytes)False>>>而bytes是二进制序列对象,只需要加上Ab意味着你想定义一个字节类型的字符串对象。#python3>>>byte_obj=b"HelloWorld!">>>type(byte_obj)>>>>>isinstance(byte_obj,str)False>>>>>>isinstance(byte_obj,bytes)对>>>但是在定义汉字字符串的时候,不能直接在前面加b,而是要用encode进行转换。>>>byte_obj=b"Hello"File"",line1SyntaxError:bytescanonlycontainASCIIliteralcharacters.>>>>>>>>str_obj="Hello">>>>>>str_obj.encode("utf-8")b'\xe4\xbd\xa0\xe5\xa5\xbd'>>>2。Python2中的str和unicode,但是在Python2中,string的类型与Python3不同,需要仔细区分。在Python2中,字符串只有unicode和str两种类型。仅unicode对象和非unicode对象的区别(其实应该叫str对象):unicode字符串(unicode类型):以Unicode码点的形式存储,人类识别的字节串形式(str类型):以字节形式存储,机器识别的形式当我们直接使用双引号或者单引号定义一个字符串时,它就是一个str字符串对象,比如这样:#python2>>>str_obj="Hello">>>>>>type(str_obj)>>>>>isinstance(str_obj,bytes)True>>>isinstance(str_obj,str)True>>>当我们在双引号或单引号前添加一个u时,表示我们定义的是unicode字符串对象,比如这样:#python2>>>unicode_obj=u"Hello">>>>>>type(unicode_obj)>>>>>isinstance(unicode_obj,bytes)False>>>isinstance(unicode_obj,str)False>>>3.如何检测对象的编码所有字符在unicode字符集中(英文称为:codepoint)都有对应的编码值。而将这些编码后的值按照一定的规则保存成二进制字节码就是我们所说的编码方式,常见的有:UTF-8、GB2312等。也就是说,当我们要将内存中的字符串持久化到硬盘上时磁盘,我们必须指定编码方式,反之,读取时,我们也必须指定正确的编码方式(这个过程称为解码)。否则会出现乱码。那么问题来了,当我们知道了对应的编码方式后,就可以正常解码了,但是并不是每时每刻都能知道应该用什么编码方式来解码呢?这个时候我们会介绍一个python库——chardet,使用前需要先安装:python3-mpipinstallchardetchardet有一个检测方法可以预测它的编码格式:>>>importchardet>>>chardet.detect('WeChat公众号:Python编程时间'.encode('gbk')){'encoding':'GB2312','confidence':0.99,'language':'Chinese'}为什么是预测呢?从上面的输出中,你会看到有一个confidence字段,表示预测的可信度,或者说成功率。但是在使用的时候,如果你的字符数少,可能会被“误诊”),比如中文只有两个字符,如下图,我们使用的是gbk编码,但是使用chardet识别为KOI8-R编码。>>>str_obj="Chinese">>>byte_obj=bytes(a,encoding='gbk')#首先得到一个gbk编码的字节>>>>>>chardet.detect(byte_obj){'encoding':'KOI8-R','confidence':0.682639754276994,'language':'Russian'}>>>>>>strstr_obj2=str(byte_obj,encoding='KOI8-R')>>>str_obj2'жпнд'soforencodingdiagnosis待定准确地说,尽量使用尽可能多的字符。Chardet支持多种语言。从官方文档我们可以看到支持以下语言(https://chardet.readthedocs.io/en/latest/supported-encodings.html)。4、编码和解码的区别编码和解码其实就是str和bytes相互转换的过程(Python2已经走了,这里以后只以Python3为例)编码:encode方法,将字符串对象转换成二进制字节序列解码:decode方法将一个二进制字节序列转换成一个字符串对象Python中的Unicode&CharacterEncodings那么如果我们真的知道它的编码格式,如何将它转换成unicode呢?有两种方法:第一种是,直接使用decode方法>>>byte_obj.decode('gbk')'Chinese'>>>第二种是使用str类转换>>>strstr_obj=str(byte_obj,encoding='gbk')>>>str_obj'Chinese'>>>5.如何设置文件编码在Python2中,默认使用ASCII编码读取,所以我们在使用Python2时,如果你的python文件中有中文,运行就会报错。SyntaxError:Non-ASCIIcharacter'\xe4'infiledemo.py原因是ASCII码表太小,无法解释中文。在Python3中,默认使用uft-8来读取,这样可以省去很多工作。对于这个问题,通常有两种解决方法:(1)第一种方法在python2中,可以用它在header中指定可以这样写,虽然看起来不错#-*-coding:utf-8-*-但是这样写太麻烦了,我一般用下面两种写法#coding:utf-8#coding=utf-8(2)第二种方法importsysreload(sys)sys.setdefaultencoding('utf-8')这里是调用sys.setdefaultencoding('utf-8')在设置默认解码方式之前,执行reload(sys),这是必须的,因为python加载sys后会删除sys.setdefaultencoding方法,我们需要重新加载sys调用sys.setdefaultencoding这个方法。以上就是我今天总结的Python开发者最关心的编码问题,但是对于编码的基础知识,还是需要借助搜索引擎提前学习一下。