编码

以’哈’来解释作示例解释所有的问题,“哈”的各种编码如下:
1. UNICODE (UTF8-16),C854;
2. UTF-8,E59388;
3. GBK,B9FE。

python中的中文编码就是一个极为头大的问题,经常抛出编码转换的异常,python中的str和unicode到底是一个什么东西呢?

  • 在python中提到unicode,一般指的是unicode对象,例如’哈哈’的unicode对象为
    u’\u54c8\u54c8’
  • 而str,是一个字节数组,这个字节数组表示的是对unicode对象编码(可以是utf-8、gbk、cp936、GB2312)后的存储的格式。这里它仅仅是一个字节流,没有其它的含义,如果你想使这个字节流显示的内容有意义,就必须用正确的编码格式,解码显示。

对于unicode对象哈哈进行编码,编码成一个utf-8编码的str-s_utf8,s_utf8就是是一个字节数组,存放的就是’\xe5\x93\x88\xe5\x93\x88’,但是这仅仅是一个字节数组,如果你想将它通过print语句输出成哈哈,那你就失望了,为什么呢?

因为print语句它的实现是将要输出的内容传送了操作系统,操作系统会根据系统的编码对输入的字节流进行编码,这就解释了为什么utf-8格式的字符串“哈哈”,输出的是“鍝堝搱”,因为 ‘\xe5\x93\x88\xe5\x93\x88’用GB2312去解释,其显示的出来就是“鍝堝搱”。这里再强调一下,str记录的是字节数组,只是某种编码的存储格式,至于输出到文件或是打印出来是什么格式,完全取决于其解码的编码将它解码成什么样子。

encode()和decode()

  • encode()的作用是将Unicode编码的字符串转换为其他编码格式。

例如: st1.encode(“utf-8”) 这句话的作用是将Unicode编码的st1编码为utf-8编码的字符串

  • decode()的作用是把其他编码格式的字符串转换成Unicode编码的字符串。

例如: st2.decode(“utf-8”) 这句话的作用是将utf-8编码的字符串st2解码为Unicode编码的字符串

字符串编码格式互相转换

除Unicode编码的字符串以外,任何一种编码的字符串要想转换为其他编码格式,必须先解码后编码

非Unicode编码–> Unicode编码–>非Unicode编码

例如,utf-8编码的字符串st想要转换为gbk编码的字符串,必须经过以下步骤:
st=st.decode(“utf-8”) #解码为Unicode编码
st=st.encode(“gbk”) #从Unicode编码编码为gbk编码

将GBK’哈哈’转换成unicode,然后再转换成UTF8

Setdefaultencoding

如上图的演示代码所示:
把s(gbk字符串)直接编码成utf-8的时候,将抛出异常,但是通过调用如下代码:

import sys
reload(sys)
sys.setdefaultencoding('gbk')

之后就可以转换成功,为什么呢?

  • 在python中str和unicode在编码和解码过程中,如果将一个str直接编码成另一种编码,会先把str解码成unicode,采用的编码为默认编码,一般默认编码是anscii,所以在上面示例代码中第一次转换的时候会出错,当设定当前默认编码为’gbk’后,就不会出错了。
  • 至于reload(sys)是因为Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入。

操作文件编码格式不同的文件

建立一个文件test.txt,文件格式用ANSI,内容为:
abc中文
用python来读取

#coding=gbk
print open("Test.txt").read()

结果:abc中文
把文件格式改成UTF-8:
结果:abc涓枃
显然,这里需要解码:

# coding=gbk
import codecs
print open("Test.txt").read().decode("utf-8")

结果:abc中文

utf-8编码分为有BOM和无BOM

上面的test.txt我是用Editplus来编辑的,但当我用Windows自带的记事本编辑并存成UTF-8格式时,
运行时报错:
Traceback (most recent call last):
File “ChineseTest.py”, line 3, in
print open(“Test.txt”).read().decode(“utf-8”)
UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\ufeff’ in position 0: illegal multibyte sequence
原来,某些软件,如notepad,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)
因此我们在读取时需要自己去掉这些字符,python中的codecs module定义了这个常量:

#coding=gbk
import codecs
data = open("Test.txt").read()
if data[:3] == codecs.BOM_UTF8:data = data[3:]
print data.decode("utf-8")

结果:abc中文

文件的编码格式和编码声明的作用

文件的编码格式对字符串的声明有什么作用呢?
文件的编码格式决定了在该源文件中声明的字符串的编码格式,例如:
str = ‘哈哈’
print repr(str)
a. 如果文件格式为utf-8,则str的值为:’\xe5\x93\x88\xe5\x93\x88’(哈哈的utf-8编码)
b. 如果文件格式为gbk,则str的值为:’\xb9\xfe\xb9\xfe’(哈哈的gbk编码)

在第一节已经说过,python中的字符串,只是一个字节数组,所以当把a情况的str输出到gbk编码的控制台时,就将显示为乱码:鍝堝搱;而当把b情况下的str输出utf-8编码的控制台时,也将显示乱码的问题,是什么也没有,也许’\xb9\xfe\xb9\xfe’用utf-8解码显示,就是空白吧。
说完文件格式,现在来谈谈编码声明的作用吧,每个文件在最上面的地方,都会用# coding=gbk 类似的语句声明一下编码,但是这个声明到底有什么用呢?到止前为止,我觉得它的作用也就是三个:

  1. 声明源文件中将出现非ascii编码,通常也就是中文;
  2. 在高级的IDE中,IDE会将你的文件格式保存成你指定编码格式。
  3. 决定源码中类似于u’哈’这类声明的将‘哈’解码成unicode所用的编码格式,也是一个比较容易让人迷惑的地方,看示例:
#coding:gbk
ss = u'哈哈'
print repr(ss)
print 'ss:%s' % ss

将这个些代码保存成一个utf-8文本,运行,你认为会输出什么呢?大家第一感觉肯定输出的肯定是:

u’\u54c8\u54c8’
ss:哈哈

但是实际上输出是:

u’\u935d\u581d\u6431’
ss:鍝堝搱

为什么会这样,这时候,就是编码声明在作怪了,在运行ss = u’哈哈’的时候,整个过程可以分为以下几步:
1) 获取’哈哈’的编码:由文件编码格式确定,为’\xe5\x93\x88\xe5\x93\x88’(哈哈的utf-8编码形式)
2) 转成 unicode编码的时候,在这个转换的过程中,对于’\xe5\x93\x88\xe5\x93\x88’的解码,不是用utf-8解码,而是用声明编码处指定的编码GBK,将’\xe5\x93\x88\xe5\x93\x88’按GBK解码,得到就是”鍝堝搱”,这三个字的unicode编码就是u’\u935d\u581d\u6431’,至止可以解释为什么print repr(ss)输出的是u’\u935d\u581d\u6431’ 了。
好了,这里有点绕,我们来分析下一个示例:

#-*- coding:utf-8 -*-
ss = u'哈哈'
print repr(ss)
print 'ss:%s' % ss

将这个示例这次保存成GBK编码形式,运行结果,竟然是:
UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xb9 in position 0: unexpected code byte
这里为什么会有utf8解码错误呢?想想上个示例也明白了,转换第一步,因为文件编码是GBK,得到的是’哈哈’编码是GBK的编码’\xb9\xfe\xb9\xfe’,当进行第二步,转换成 unicode的时候,会用UTF8对’\xb9\xfe\xb9\xfe’进行解码,而大家查utf-8的编码表会发现,utf8编码表(关于UTF- 8解释可参见字符编码笔记:ASCII、UTF-8、UNICODE)中根本不存在,所以会报上述错误。

json文件的中文编码

用Python读取Json文件时经常用到json.load()函数,该函数对json文件的格式是有要求的

  1. json文件是utf-8 without BOM编码的,那么可以直接用json.load(filename)函数读取json文件的内容
  2. json文件是utf-8 with BOM编码的,不能用json.load()函数读取,json.load()不能正确识别
  3. json文件时其他编码的,比如gbk, 要把json文件的编码格式作为一个参数传给json.load():
    eg. json.load(filename,”gbk”)

使用python的chardet库获得文件编码

首先需要安装chardet库: 略

示例1:识别传入的字符串的编码,并转换为unicode和utf8编码格式

import chardet
def _smartcode(stream):"""smart recove stream into UTF-8"""ustring = streamcodedetect = chardet.detect(ustring)["encoding"]print codedetecttry:print ustringustring = unicode(ustring, codedetect)print ustringreturn "%s %s"%("",ustring.encode('utf8'))except:return u"bad unicode encode try!"

示例2:识别文件编码格式并进行转换

# coding: UTF-8
import sys
import os
import chardetdef print_usage():print '''usage:change_charset [file|directory] [charset] [output file]\nfor example:change 1.txt utf-8 n1.txtchange 1.txt utf-8change . utf-8change 1.txt
'''
def get_charset(s):return chardet.detect(s)['encoding']def remove(file_name):os.remove(file_name)def change_file_charset(file_name, output_file_name, charset):f = open(file_name)s = f.read()f.close()if file_name == output_file_name or output_file_name == "":remove(file_name)old_charset = get_charset(s)u = s.decode(old_charset)if output_file_name == "":output_file_name = file_namef = open(output_file_name, 'w')s = u.encode(charset)f.write(s)f.close()def do(file_name, output_file_name, charset):if os.path.isdir(file_name):for item in os.listdir(file_name):try:if os.path.isdir(file_name+"/"+item):do(file_name+"/"+item, "", charset)else:change_file_charset(file_name+"/"+item, "", charset)except OSError, e:print eelse:change_file_charset(file_name, output_file_name, charset)if __name__ == '__main__':length = len(sys.argv)if length == 1:print_usage()elif length == 2:do(sys.argv[1], "", "utf-8")elif length == 3:do(sys.argv[1], "", sys.argv[2])elif length == 4:do(sys.argv[1], sys.argv[3], sys.argv[2])else:print_usage()

【参考:参考1 参考2 参考3】

Python-中文编码相关推荐

  1. python中文编码-彻底弄懂python编码

    在编写python程序的过程中,中英文混用经常会出现编码问题.围绕此问题,本文首先介绍编码的含义及常用编码,随后列举几个python经常遇到的编码异常及解决方法,接着列举笔者在实践中遇到的异常出现的情 ...

  2. python中文编码-python中文编码与json中文输出问题详解

    前言 python2.x版本的字符编码有时让人很头疼,遇到问题,网上方法可以解决错误,但对原理还是一知半解,本文主要介绍 python 中字符串处理的原理,附带解决 json 文件输出时,显示中文而非 ...

  3. Python中文编码 - Python零基础入门教程

    目录 一.前言 二.为什么会出现乱码 三.如何解决乱码 四.重点总结 五.猜你喜欢 一.前言 零基础 Python 学习路线推荐 : Python 学习目录 >> Python 基础入门 ...

  4. python unicode编码转换中文_Python入门高级教程--Python 中文编码

    Python 中文编码 前面章节中我们已经学会了如何用 Python 输出 "Hello, World!",英文没有问题,但是如果你输出中文字符 "你好,世界" ...

  5. [Python] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题

    最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下 ...

  6. [Python] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题...

    最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下 ...

  7. python中文编码-Python中文乱码(转)

    转自:https://blog.csdn.net/apache0554/article/details/53889253 前言:中文编码问题一直是程序员头疼的问题,而Python2中的字符编码足矣令新 ...

  8. Python 中文编码

    现象描述 我们用 Python 输出 "Hello, World!",英文没有问题, 但是如果你输出中文字符"你好,世界"就有可能会碰到中文编码问题. Pyth ...

  9. 【ArcGIS遇上Python】ArcGIS Python中文编码问题案例详解

    前面的文章<ArcGIS Python获取Shapefile矢量数据字段名称>我们已经学会了如何用 Python 获取中文路径下的shp数据的所有字段,英文没有问题,但是如果你输出中文路径 ...

  10. Python中文编码问题详解

    中文编码问题是用中文的程序员经常头大的问题,在python下也是如此,那么应该怎么理解和解决python的编码问题呢? 我们要知道python内部使用的是unicode编码,而外部却要面对千奇百怪的各 ...

最新文章

  1. endnote能自动翻译吗_人工智能能翻译古文吗?跟小编点评专业翻译PK人工智能翻译...
  2. android 获取网卡mac_在Android机顶盒上 怎么样获取有线网卡MAC地址?
  3. php网站入门鹿泉银山,01PHP编程新手入门第一步
  4. python去掉txt文件行尾换行
  5. java+jtextfield+取值_[求助]JTextfield 取值问题!
  6. 用Cython加速Python到“起飞”
  7. 盼望的意思是什么,怎么用盼望造句?
  8. vscode-更换图标主题VSCode Icons.
  9. oracle ntile函数,Oracle分析函数ntile
  10. web前端面试题【html+css+js+框架】
  11. 灵魂电钢琴音源 Native Instruments George Duke Soul Treasures
  12. Unity Shader数学基础 -- Shader入门精要学习(3)
  13. 半闲居士视觉SLAM十四讲笔记(5)相机与图像 - part 2 图像及 OpenCV 操作、点云拼接
  14. FX3U和三菱伺服控制的框架标准程序 回原点、JOG手动、绝对定位、相对定位、控制等部分
  15. PHP Failed opening required
  16. Windows 8系统IE10无法安装Flash Player插件的解决办法
  17. matlab 时间坐标轴,matlab坐标轴范围
  18. jpeg2000(j2k)图像编码解码:c++实现openjpeg内存流接口(memory stream)
  19. EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs初始化的一些样式处理
  20. 排中律与实无穷问题的性质分析

热门文章

  1. MATLAB R2009a完美安装及下载
  2. 【转】幻想传说:全技能奥义、料理、物品、称号、交易品 获得条件(图文)...
  3. 主要的竞争情报分析研究方法
  4. 轻松解决2013 lost connection to mysql server at ‘reading initial communication packet‘, system error: 0“
  5. MM买裤子杀价全过程
  6. echarts实现横向柱图文字在柱图上面
  7. 我在CSDN和Unity有个约会
  8. 语义分割,将RGB三通道的lable转为单通道
  9. 天津市第三中心医院院长杜智:患者医药费超标 罚医生护士
  10. 我的Java乱卷之路