python编码总结(编码类型、格式、转码)


Posted in Python onJuly 01, 2016

本文详细总结了python编码。分享给大家供大家参考,具体如下:

【所谓unicode】

unicode是一种类似于符号集的抽象编码,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。也就是它只是一种内部表示,不能直接保存。所以存储时需要规定一种存储形式,比如utf-8和utf-16等。理论上unicode是一种能够容纳全世界所有语言文字的编码方案。(其他编码格式不再多说)

【所谓GB码】

GB就是“国标”的意思,即:中华人民共和国国家标准。GB码是面向汉字的编码,包括GB2312(GB2312-80),GBK,GB18030,表示范围从小到大递增,而且基本是向下兼容的。此外经常遇到一种叫做CP936的编码,实际上可以大概看做是GBK。

【判断编码】

1、使用isinstance(s, str)来判断一个字符串是否为一般字符串(str为ascii类型的字符串,utf-8、utf-16、GB2312、GBK等都是ascii类型的字符串);

使用isinstance(s, unicode)来判断一个字符串是否为unicode编码形式的字符串(unicode编码的字符串才是unicode类型的字符串)。

2、使用type()或者.__class__

在编码正确的情况下:

例如:stra = "中", 则使用type(stra)的结果是<type 'str'>,表明为ascii类型字符串;

例如:strb = u"中", 则使用type(strb)的结果是<type 'unicode'>,表明为unicode类型字符串。

tmp_str = 'tmp_str'
print tmp_str.__class__   #<type 'str'>
print type(tmp_str)    #<type 'str'>
print type(tmp_str).__name__ #str
tmp_str = u'tmp_str'
print tmp_str.__class__   #<type 'unicode'>
print type(tmp_str)    #<type 'unicode'>
print type(tmp_str).__name__ #unicode

3、最好的办法是使用chardet判断,特别是在web相关的操作中,例如抓取html页面内容时,页面的charset标签只是标示编码,有时候不对,而且页面内容中一些中文可能超出了标示编码的范围,此时用charset检测最为方便准确。

(1)安装办法:下载chardet后,将解压得到的chardet文件夹放在Python安装目录的\Lib\site-packages目录下,在程序中使用import chardet即可。

(2)使用办法1:检测全部内容判断编码

import urllib2
import chardet
res = urllib2.urlopen('https://3water.com')
res_cont = res.read()
res.close()
print chardet.detect(res_cont) #{'confidence': 0.99, 'encoding': 'utf-8'}

detect函数返回值为一个包含2个键值对的字典,第一个是检测置信度,第二个就是检测到的编码形式。

(3)使用办法2:检测部分内容判断编码,提高速度

import urllib2
from chardet.universaldetector import UniversalDetector
res = urllib2.urlopen('https://3water.com')
detector = UniversalDetector()
for line in res.readlines():
 #detect untill reach threshold
 detector.feed(line)
 if detector.done:
  break
detector.close()
res.close()
print detector.result
#{'confidence': 0.99, 'encoding': 'utf-8'}

【转换编码】

1、从具体的编码(ISO-8859-1[ASCII码],utf-8,utf-16,GBK,GB2312等)转换为unicode,直接使用unicode(s, charset)或者s.decode(charset),其中charset为s的编码(注意unicode在使用decode()时会出错);

#将任意字符串转换为unicode
def to_unicode(s, encoding):
 if isinstance(s, unicode):
  return s
 else:
  return unicode(s, encoding)

注意:这里在decode()的时候,如果遇到非法字符(比如不标准的全角空格\xa3\xa0,或者\xa4\x57,真正的全角空格是\xa1\xa1),就会报错。

解决办法:采用'ignore'模式,即:stra.decode('...', 'ignore').encode('utf-8')。

解释:decode的函数原型是decode([encoding],[errors='strict']),可以用第二个参数控制错误处理的策略。

默认的参数就是strict,代表遇到非法字符时抛出异常;如果设置为ignore,则会忽略非法字符;如果设置为replace,则会用?取代非法字符;如果设置为xmlcharrefreplace,则使用XML的字符引用。

2、从unicode转换为具体的编码,也是直接用s.encode(charset),其中s为unicode编码,charset为具体的编码(注意非unicode在使用encode()时会出错);

3、自然地,从一种具体编码转换为另一种具体编码,就可以先decode成unicode再encode成最终编码了。

【python命令行编码(系统编码)】

用python自带的locale模块来检测命令行的默认编码(也就是系统的编码)和设置命令行编码:

import locale
#get coding type
print locale.getdefaultlocale() #('zh_CN', 'cp936')
#set coding type
locale.setlocale(locale.LC_ALL, locale='zh_CN.GB2312')
print locale.getlocale() #('zh_CN', 'gb2312')

表明当前系统的内部编码是cp936,近似于GBK。实际上中文XP和WIN7的系统内部编码都是cp936(GBK)。

【python代码中的编码】

1、python代码中的字符串在未被指定编码的情况下,默认编码与代码文件本身的编码一致。举个例子:str = '中文'这个字符串,如果是在utf8编码的代码文件中,该字符串就是utf8编码;如果是在gb2312的文件中,该字符串就是gb2312编码。那么代码文件本身的编码怎么知道呢?

(1)自己指定代码文件的编码:在代码文件的头部加上“#-*- coding:utf-8 -*-”来声明该代码文件为utf-8编码。此时未被指定编码的字符串的编码都变成了utf-8。

(2)在没有指定代码文件的编码时,创建代码文件时使用的是python默认采用的编码(一般来说是ascii码,在windows中实际保存为cp936(GBK)编码)。通过sys.getdefaultencoding()和sys.setdefaultencoding('...')来获取和设置该默认编码。

import sys
reload(sys)
print sys.getdefaultencoding() #ascii
sys.setdefaultencoding('utf-8')
print sys.getdefaultencoding() #utf-8

结合(1)和(2)做个试验:指定代码文件编码为utf-8时,用notepad++打开显示的是utf-8无DOM编码;未指定代码文件编码时,用notepad++打开显示的是ANSI编码(压缩编码,默认的保存编码形式)。

python编码总结(编码类型、格式、转码)

(3)如何永久地将python默认采用的编码设置为utf-8呢?有2种方法:

第一个方法<不推荐>:编辑site.py,修改setencoding()函数,强制设置为 utf-8;

第二个方法<推荐>:增加一个名为 sitecustomize.py的文件,存放在安装目录下的\Lib\site-packages目录下

sitecustomize.py是在site.py被import执行的,因为 sys.setdefaultencoding()是在site.py的结尾处被删除的,所以可以在 sitecustomize.py使用 sys.setdefaultencoding()。

2、python代码中的字符串如果被指定了编码,举个例子:str = u'中文',该字符串的编码被指定为unicode(即python的内部编码)。

(1)这里有个误区需要注意!假如在py文件中有如下代码:

stra = u"中"
print stra.encode("gbk")

按上面说的stra是unicode形式,直接encode称gbk编码应该没问题啊?但是实际执行时会报错“UnicodeEncodeError: 'gbk' codec can't encode character u'\xd6' in position 0: illegal multibyte sequence”。

原因在于:python解释器在导入python代码文件并执行时,会先查看文件头有没有编码声明(例如#coding:gbk等)。如果发现声明,会将文件中的字符串都先解释成unicode的形式(这里先用默认编码gbk(cp936)将stra解码成unicode编码'd6d0'后保存),之后执行stra.encode('gbk')时,由于stra已经是unicode编码且'd6d0'在gbk的编码范围内,所以编码不会出现错误;如果文件头没有编码声明,则不会进行上述过程中的解码操作(这里就直接使用stra的unicode编码'd6'),之后执行stra.encode('gbk')时,由于'd6'不在gbk的编码范围所以报错。

(2)为避免这种类型的错误,最好在代码文件头上声明编码,或者麻烦点每次使用setdefaultencoding()。

(3)总的来说就是unicode是python解释器的内码,所有代码文件在导入并执行时,python解释器会先将字符串使用你指定的编码形式解码成unicode,然后再进行各种操作。所以不管是对字符串的操作,还是正则表达式,还是读写文件等等最好都通过unicode来进行。

【python中其他编码】

文件系统的编码:sys.getfilesystemencoding()
终端的输入编码:sys.stdin.encoding
终端的输出编码:sys.stdout.encoding

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python脚本实现DNSPod DNS动态解析域名
Feb 14 Python
在Python中操作文件之truncate()方法的使用教程
May 25 Python
简介二分查找算法与相关的Python实现示例
Aug 26 Python
python PIL模块与随机生成中文验证码
Feb 27 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
May 17 Python
Python输出带颜色的字符串实例
Oct 10 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 Python
python多线程并发实例及其优化
Jun 27 Python
python实现Pyecharts实现动态地图(Map、Geo)
Mar 25 Python
Numpy 理解ndarray对象的示例代码
Apr 03 Python
Python 如何对文件目录操作
Jul 10 Python
Python编码类型转换方法详解
Jul 01 #Python
Python面向对象编程中关于类和方法的学习笔记
Jun 30 #Python
Python中的time模块与datetime模块用法总结
Jun 30 #Python
详解Swift中属性的声明与作用
Jun 30 #Python
为Python的Tornado框架配置使用Jinja2模板引擎的方法
Jun 30 #Python
Python的Flask框架中的Jinja2模板引擎学习教程
Jun 30 #Python
Python的Tornado框架实现异步非阻塞访问数据库的示例
Jun 30 #Python
You might like
php 文本文件的读取效率
2012/02/10 PHP
解析php下载远程图片函数 可伪造来路
2013/06/25 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
php上传图片存入数据库示例分享
2014/03/11 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
详解Laravel设置多态关系模型别名的方式
2019/10/17 PHP
Jquery选择器 $实现原理
2009/12/02 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
js实现的简单radio背景颜色选择器代码
2015/08/18 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
AngularJs表单校验功能实例代码
2017/02/09 Javascript
jQuery实现腾讯信用界面(自制刻度尺)样式
2017/08/15 jQuery
解决jquery有正确返回值但不执行success函数的问题
2018/08/20 jQuery
关于layui flow loading占位图的实现方法
2019/09/21 Javascript
vue 实现通过vuex 存储值 在不同界面使用
2019/11/11 Javascript
js实现带积分弹球小游戏
2020/07/21 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
python实现简单的计时器功能函数
2015/03/14 Python
python简单实现基数排序算法
2015/05/16 Python
Python中常用信号signal类型实例
2018/01/25 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
djang常用查询SQL语句的使用代码
2019/02/15 Python
Python基本数据结构与用法详解【列表、元组、集合、字典】
2019/03/23 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
Tory Burch德国官网:美国时尚生活品牌
2018/01/03 全球购物
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
捷克建筑材料网上商店:DEK.cz
2021/03/06 全球购物
《赠汪伦》教学反思
2014/04/12 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
祖国在我心中演讲稿300字
2014/05/04 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
异地恋情人节寄语
2015/02/28 职场文书
抢劫罪辩护词
2015/05/21 职场文书