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中的__slots__使用示例
Feb 26 Python
Python中返回字典键的值的values()方法使用
May 22 Python
Python实现对象转换为xml的方法示例
Jun 08 Python
在python中获取div的文本内容并和想定结果进行对比详解
Jan 02 Python
Python3字符串encode与decode的讲解
Apr 02 Python
Python+numpy实现矩阵的行列扩展方式
Nov 29 Python
使用Tkinter制作信息提示框
Feb 18 Python
使用Python3 poplib模块删除服务器多天前的邮件实现代码
Apr 24 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
May 22 Python
Python 如何查找特定类型文件
Aug 17 Python
Python列表的索引与切片
Apr 07 Python
Python用any()函数检查字符串中的字母以及如何使用all()函数
Apr 14 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
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
php GUID生成函数和类
2014/03/10 PHP
php集成套件服务器xampp安装使用教程(适合第一次玩PHP的新手)
2015/06/03 PHP
实例简介PHP的一些高级面向对象编程的特性
2015/11/27 PHP
php基于ob_start(ob_gzhandler)实现网页压缩功能的方法
2017/02/18 PHP
laravel-admin 在列表页添加自定义按钮的例子
2019/09/30 PHP
JS 获取span标签中的值的代码 支持ie与firefox
2009/08/24 Javascript
Javascript 键盘keyCode键码值表
2009/12/24 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
javascript实现无限级select联动菜单
2015/01/02 Javascript
AngularJS中的指令全面解析(必看)
2016/05/20 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
jQuery中animate()的使用方法及解决$(”body“).animate({“scrollTop”:top})不被Firefox支持的问题
2017/04/04 jQuery
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
2017/05/17 Javascript
angularjs2 ng2 密码隐藏显示的实例代码
2017/08/01 Javascript
jQuery实现简单的下拉菜单导航功能示例
2017/12/07 jQuery
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
2018/10/12 Javascript
js作用域和作用域链及预解析
2019/04/11 Javascript
Node.js系列之发起get/post请求(2)
2019/08/30 Javascript
关于vue.js中实现方法内某些代码延时执行
2019/11/14 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
[02:05]2014DOTA2西雅图国际邀请赛 BBC第二天小组赛总结
2014/07/11 DOTA
python测试驱动开发实例
2014/10/08 Python
Python跨文件全局变量的实现方法示例
2017/12/10 Python
浅析PyTorch中nn.Module的使用
2019/08/18 Python
html5版canvas自由拼图实例
2014/10/15 HTML / CSS
阿玛尼意大利官网:Armani意大利
2018/10/30 全球购物
什么是.net
2015/08/03 面试题
《九色鹿》教学反思
2014/02/27 职场文书
新年抽奖获奖感言
2014/03/02 职场文书
住房租房协议书
2014/08/20 职场文书
2014年关工委工作总结
2014/11/17 职场文书
2014年党务公开工作总结
2014/12/09 职场文书
社区艾滋病宣传活动总结
2015/05/07 职场文书
傲慢与偏见电影观后感
2015/06/10 职场文书
房屋质量投诉书
2015/07/02 职场文书