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二维码生成库qrcode安装和使用示例
Dec 16 Python
python根据时间生成mongodb的ObjectId的方法
Mar 13 Python
Python手机号码归属地查询代码
May 04 Python
Python实现多级目录压缩与解压文件的方法
Sep 01 Python
Python去除字符串前后空格的几种方法
Mar 04 Python
解决Python3 抓取微信账单信息问题
Jul 19 Python
python中bytes和str类型的区别
Oct 21 Python
Python3.7+tkinter实现查询界面功能
Dec 24 Python
python实现用户名密码校验
Mar 18 Python
Python基于数列实现购物车程序过程详解
Jun 09 Python
python爬取天气数据的实例详解
Nov 20 Python
python中remove函数的踩坑记录
Jan 04 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单文件版在线代码编辑器
2015/03/12 PHP
学习php设计模式 php实现备忘录模式(Memento)
2015/12/09 PHP
js的touch事件的实际引用
2014/10/13 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
jQuery实现图片走马灯效果的原理分析
2016/01/16 Javascript
Bootstrap创建可折叠的组件
2016/02/23 Javascript
Angularjs结合Bootstrap制作的一个TODO List
2016/08/18 Javascript
使用JS读取XML文件的方法
2016/11/25 Javascript
js实现刷新页面后回到记录时滚动条的位置【两种方案可选】
2016/12/12 Javascript
JS中Select下拉列表类(支持输入模糊查询)功能
2017/01/17 Javascript
使用JS实现导航切换时高亮显示的示例讲解
2018/08/22 Javascript
[02:27]刀塔重生降临
2015/10/14 DOTA
[50:34]VGJ.T vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python服务器与android客户端socket通信实例
2014/11/12 Python
用Python计算三角函数之acos()方法的使用
2015/05/15 Python
Python结巴中文分词工具使用过程中遇到的问题及解决方法
2017/04/15 Python
python爬取淘宝商品销量信息
2018/11/16 Python
Python实现的批量修改文件后缀名操作示例
2018/12/07 Python
python实现QQ邮箱/163邮箱的邮件发送
2019/01/22 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
python实现磁盘日志清理的示例
2020/11/05 Python
python动态规划算法实例详解
2020/11/22 Python
python 模块导入问题汇总
2021/02/01 Python
python 多线程爬取壁纸网站的示例
2021/02/20 Python
使用CSS禁止textarea调整大小功能的方法
2015/03/13 HTML / CSS
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
机械工程师求职自我评价
2013/09/23 职场文书
领导干部对照检查材料
2014/08/24 职场文书
党支部组织生活会整改方案
2014/09/30 职场文书
专家推荐信怎么写
2015/03/25 职场文书
2015年依法行政工作总结
2015/04/29 职场文书
财务管理制度范本
2015/08/04 职场文书
Vue3中toRef与toRefs的区别
2022/03/24 Vue.js
python manim实现排序算法动画示例
2022/08/14 Python