Python中的编码问题


视频汇总首页:http://edu.51cto.com/lecturer/index/user_id-4626073.htmlhtml

对于Python的初学者来讲,编码问题至关使人头疼。本文就根据我在学习过程当中遇到的问题简单谈一下Python中的编码。首先简单介绍一下几种常见的编码。python

1、几种常见的字符编码windows

ASCII码数组

ASCII码是基于拉丁字码的一套电脑编码系统。它对英语字符与二进制位之间的关系作了统一的规定,使用指定的7位或8为二进制数组合来表示128或256种可能的字符。标准ASCII码也叫基础ASCII码,使用7位二进制来表示全部的大写和小写字母,数字0到九、标点符号,以及在美式英语中使用的特殊控制字符。微信

英语中英文字母用128个符号编码就够了,可是用来表示其余语言,128个符号显然是不够的。好比,在法语中,字母上方有注音符号,它就没法用ASCII码表示。至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。ide

Unicode学习

Unicode统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每一个字符设定了统一而且惟一的二进制编码,以知足跨语言、跨平台进行文本转换、处理的要求。字体

UTF-8网站

UTF-8(8位元Universal Character Set/Unicode Transformation Format)是一种针对Unicode的可变长度字符编码。UTF-8最大的一个特色,是它是一种变长的编码方式。它能够用来表示Unicode标准中的任何字符,且其编码中的第一个字节与ASCII相容。UTF-8是在互联网上使用最广的一种Unicode的实现方式。编码

2、Python中的字符串类型

Python中的字符串有两种类型:str类型和unicode类型。以字符串“中文”赋值给变量为例:

wKioL1ZzdrKDdTIfAAAIpaYu4Ao256.png或者wKioL1ZzdsDyOpeVAAAJcOrpI8c627.png

在Python中,为了统一不一样编码的字符串的表示,同时简化字符串的处理,其内部提供了一种统一化的文本类型unicode,即第二种形式的字符串。unicode类型的字符串只处理文本,并把文本以unicode形式在内部存储。unicode类型的做用只用于代码内部字符串的处理,而不关心外部文本的具体格式,能够看做是文本的抽象表示。前者定义了一个字符串,后者定义了一个unicode编码的字符串。

可是实际上外界文本的不一样编码格式众多。好比向一个网站提交数据,其有可能要求utf-8的编码或者gbk的编码,不一样的编码类型的内容是不一样的, 这就须要将程序内部字符串转换成能够与外界交互的编码(如:utf-8,ascii,gdb等)。Python默认使用str类型来操做。严格来说,str并不必定是文本,它也有多是二进制的内容,它提供的实际上是字节的组合(unicode类型提供的是unicode字符集的组合),只是若是str中恰好是某种形式编码的文本,它即可以当作文本处理(print等)。

3、python中常遇到的编码问题

如下问题只有在Python2.x版本中出现,由于3.X版本中python环境就只有unicode类型的字符串了,即全部程序中处理的都会自动转换成unicode字符串。

1. 代码文件编码声明

编写Python脚本时,教程都会让咱们把“# -*- coding: utf-8 -*-”加在代码文件的第一行。这句话是告诉python这个文件里的文本用utf-8编码。Python默认将代码文件内容当作ASCII编码处理,所以当文件中存在中文时就会抛出异常。加上这句编码声明后,Python就会依照utf-8的编码形式解读其中的字符,然会转换成unicode编码内部处理使用。注意这句编码声明必定要放在第一行或者第二行才生效,我以前就将它放在了其余位置,结果将源代码文件从windows移动到Linux后,出现了编码问题,文件中的中文注释全成了乱码。由于Windows中默认编码为gbk,Linux默认编码为utf-8。

或者也可使用下面的语句来设置编码方式:

wKioL1ZzduqwVkQpAAANI8ItFRU716.png

2. 编码转换

编写python过程当中常常遇到报错“UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1: ordinal not in range(128)”,为何会出这样的报错呢?

第二节提到,字符串在Python内部使用unicode编码,所以,在作编码转换时,一般须要以unicode做为中间编码,即先将其余编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另外一种编码。

decode的做用是将普通字符串按照参数中的编码格式进行解析,而后生成对应的unicode对象。如str1.decode(‘gb2312′),表示将字符串str1按照gb2312编码解析为unicode对象。

encode的做用正好相反,是将一个unicode对象转换为参数中指定的编码格式的普通字符。如str2.encode(‘gb2312′),表示将unicode对象str2转换成gb2312编码的字符串。

所以,转码的时候必定要先搞明白,字符串str是什么编码,而后decode成unicode,而后再encode成其余编码。

代码中字符串的默认编码与代码文件自己的编码一致。也就是说,在utf8的文件中,字符串就是utf8编码,若是是在gb2312的文件中,则其编码为gb2312。一般,在没有指定特定的编码方式时,都是使用的系统默认编码建立的代码文件。

若是字符串是这样定义:s=u’中文’

则该字符串就被定义为unicode对象了,即python的内部编码,而与代码文件自己的编码无关。所以,对于这种状况作编码转换,只须要直接使用encode方法将其转换成指定编码便可。

若是一个字符串已是unicode了,再进行解码则将出错,所以一般要对其编码方式是否为unicode进行判断:

isinstance(s, unicode)  #用来判断s是否为unicode


一样,用非unicode编码形式的str来encode会报错 。

所以,程序会提示:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1: ordinal not in range(128),是由于Python调用了ASCII编码解码程序去处理unicode对象,致使抛出异常(ordinal not in range(128))。解决办法则是用上一小节提到的第二种设置编码的方式来修改默认的编码模式便可。

3. 输出打印

咱们在windows控制台下打印中文时,常常出现屏幕上打印出的字和咱们想要的结果不一致的状况。这是因为python编码与控制台编码不一致形成的。Windows下控制台中的编码默认使用的是gbk,而在代码中使用的是utf-8,python按照utf-8编码打印到gbk编码的控制台下天然就不能打印出正确的汉字。

解决办法一个是将源代码的编码方式改为gbk,也就是将源代码文件的第一行改为:

# -*- coding: gbk -*-


另外一种方式是保持源代码文件的utf-8编码方式不变,而是在声明带中文的变量前u,如:s1=u’中文’,这样就能够正确打印中文了。

这里的u表示将后面跟的字符串以unicode格式存储。python会根据代码第一行声明的utf-8编码识别代码中的汉字,而后转换成unicode对象以unicode格式存在于内存中,而若是不加u,代表这仅仅是一个使用某种编码的字符串,编码格式取决于python对源码文件编码的识别,这里就是utf-8。Python在向控制台输出unicode对象的时候会自动根据输出环境的编码进行转换,但若是输出的不是unicode对象而是普通字符串,则会直接按照字符串的编码输出字符串,从而出现上面的现象。

4. 文件的读取

在对文件内容进行读取时也常常出现编码问题。这里咱们首先来了解一下文件编码。

文件编码即文件的编码方式。严格意义上来讲,文件没有编码之说,都是按二进制格式保存在硬盘中的,只是在写入读取时需使用对应的编码进行处理,以便操做系统配合相关软件/字体,绘制到屏幕中给人看。因此关键问题是得知道文件内容是使用什么方式编码成二进制码存入到磁盘中的。

Linux中Vim下可以使用命令set fileencoding来查看文件编码。

Windows中txt文件点击“文件”–>“另存为”,查看“编码”显示的编码方式(ANSI:非Unicode编码方式,对于英文系统即ASCII编码,中文系统则为GB2312或Big5编码;其他三种为“Unicode”(对应UTF-16 LE)、“Unicode big endian”(对应UTF-16 BE)和“UTF-8”)。

知道文件编码方式后,只须要在读取文件时使用相同的编码方式对内容进行解码就能得到正确的文件内容。

wKiom1ZzdybBqEBgAAAwCsl18wc887.png

但不少状况下咱们无从知晓文件的编码方式,此时可使用python提供的Chardet包。

Character encoding auto-detection(自动字符探测器),Python中一个强力的编码检测包。使用方式很是简单。

wKioL1Zzd0-Bog3xAAAjrJ6VaUs414.png

知道字符串的编码后就能够利用decode和encode实现编码的转换获得正确的文件内容了。

所以,Python中的编码问题解决方式总结起来就是:保证字符串的编码及解码方式一致,了解了文中提到相关知识相信能解决Python中大部分的编码问题了。

wKiom1Zzd1mzWkd1AAC7xM3r2nY215.jpg

相关文章
相关标签/搜索