python编码处理

开始

用python处理中文时,读取文件或消息,http参数等等

一运行,发现乱码(字符串处理,读写文件,print)

然后,大多数人的做法是,调用encode/decode进行调试,并没有明确思考为何出现乱码

所以调试时最常出现的错误

错误1

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)

错误2

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

首先

必须有大体概念,了解下字符集,字符编码

ASCII | Unicode | UTF-8 | 等等

字符编码笔记:ASCII,Unicode和UTF-8

淘宝搜索技术博客-中文编码杂谈

str 和 unicode

str和unicode都是basestring的子类

所以有判断是否是字符串的方法

def is_str(s):
    return isinstance(s, basestring)

str和unicode 转换

decode 文档

encode 文档

str  -> decode('the_coding_of_str') -> unicode
unicode -> encode('the_coding_you_want') -> str

区别

str是字节串,由unicode经过编码(encode)后的字节组成的

声明方式

s = '中文'
s = u'中文'.encode('utf-8')

>>> type('中文')
<type 'str'>

求长度(返回字节数)

>>> u'中文'.encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'
>>> len(u'中文'.encode('utf-8'))
6

unicode才是真正意义上的字符串,由字符组成

声明方式

s = u'中文'
s = '中文'.decode('utf-8')
s = unicode('中文', 'utf-8')

>>> type(u'中文')
<type 'unicode'>

求长度(返回字符数),在逻辑中真正想要用的

>>> u'中文'
u'\u4e2d\u6587'
>>> len(u'中文')
2

结论

搞明白要处理的是str还是unicode, 使用对的处理方法(str.decode/unicode.encode)

下面是判断是否为unicode/str的方法

>>> isinstance(u'中文', unicode)
True
>>> isinstance('中文', unicode)
False

>>> isinstance('中文', str)
True
>>> isinstance(u'中文', str)
False

简单原则:不要对str使用encode,不要对unicode使用decode (事实上可以对str进行encode的,具体见最后,为了保证简单,不建议)

>>> '中文'.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

>>> u'中文'.decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

不同编码转换,使用unicode作为中间编码

#s是code_A的str
s.decode('code_A').encode('code_B')

文件处理,IDE和控制台

处理流程,可以这么使用,把python看做一个水池,一个入口,一个出口

入口处,全部转成unicode, 池里全部使用unicode处理,出口处,再转成目标编码(当然,有例外,处理逻辑中要用到具体编码的情况)

读文件

外部输入编码,decode转成unicode

处理(内部编码,统一unicode)

encode转成需要的目标编码

写到目标输出(文件或控制台)

IDE和控制台报错,原因是print时,编码和IDE自身编码不一致导致
输出时将编码转换成一致的就可以正常输出

>>> print u'中文'.encode('gbk')
����
>>> print u'中文'.encode('utf-8')
中文

建议

规范编码

统一编码,防止由于某个环节产生的乱码

环境编码,IDE/文本编辑器, 文件编码,数据库数据表编码

保证代码源文件编码

这个很重要

py文件默认编码是ASCII, 在源代码文件中,如果用到非ASCII字符,需要在文件头部进行编码声明 文档

不声明的话,输入非ASCII会遇到的错误,必须放在文件第一行或第二行

File "XXX.py", line 3
SyntaxError: Non-ASCII character '\xd6' in file c.py on line 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

声明方法

# -*- coding: utf-8 -*-
或者
#coding=utf-8

若头部声明coding=utf-8, a = '中文' 其编码为utf-8

若头部声明coding=gb2312, a = '中文' 其编码为gbk

so, 同一项目中所有源文件头部统一一个编码,并且声明的编码要和源文件保存的编码一致(编辑器相关)

在源代码用作处理的硬编码字符串,统一用unicode

将其类型和源文件本身的编码隔离开, 独立无依赖方便流程中各个位置处理

if s == u'中文':  #而不是 s == '中文'
    pass
#注意这里 s到这里时,确保转为unicode

以上几步搞定后,你只需要关注两个 unicode和 你设定的编码(一般使用utf-8)

处理顺序

1. Decode early
2. Unicode everywhere
3. Encode later

相关模块及一些方法

获得和设置系统默认编码

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> sys.getdefaultencoding()
'utf-8'

str.encode('other_coding')

在python中,直接将某种编码的str进行encode成另一种编码str

#str_A为utf-8
str_A.encode('gbk')

执行的操作是
str_A.decode('sys_codec').encode('gbk')
这里sys_codec即为上一步 sys.getdefaultencoding() 的编码

'获得和设置系统默认编码'和这里的str.encode是相关的,但我一般很少这么用,主要是觉得复杂不可控,还是输入明确decode,输出明确encode来得简单些(个人观点)

chardet

文件编码检测,下载

>>> import chardet
>>> f = open('test.txt','r')
>>> result = chardet.detect(f.read())
>>> result
{'confidence': 0.99, 'encoding': 'utf-8'}

\u字符串转对应unicode字符串

>>> u'中'
u'\u4e2d'

>>> s = '\u4e2d'
>>> print s.decode('unicode_escape')
中

>>> a = '\\u4fee\\u6539\\u8282\\u70b9\\u72b6\\u6001\\u6210\\u529f'
>>> a.decode('unicode_escape')
u'\u4fee\u6539\u8282\u70b9\u72b6\u6001\u6210\u529f'

python unicode文档

入口

转自:http://wklken.me/posts/2013/08/31/python-extra-coding-intro.html

欢迎Star我的开源Web框架Blade:http://github.com/biezhi/blade

时间: 2025-01-02 02:58:31

python编码处理的相关文章

Python编码错误的处理

如题,我用python 解析文件(文件中含有中文),并写入其他文件时报错: UnicodeEncodeError: 'ascii' codec can't encode characters 经过google大神的指导,确定以下解决方式: #coding:utf-8import sys reload(sys) sys.setdefaultencoding('utf-8') 疑问:为什么需要reload呢? grep -r -i 'setdefaultencoding' /usr/lib/pyth

python编码编码转换问题

问题描述 python编码编码转换问题 sent = unicode(sent,'utf-8') UnicodeDecodeError: 'utf8' codec can't decode byte 0xce in position 0: invalid continuation byte 解决方案 要在你的python文件头加一句utf8编码,你百度搜一下,我忘记具体怎么写了,反正只要一句话! 解决方案二: 你的sent是什么编码的字符串,它不能被UTF8 decode

Python 编码处理-str与Unicode的区别_python

一篇关于STR和UNICODE的好文章 整理下python编码相关的内容 注意: 以下讨论为Python2.x版本, Py3k的待尝试 开始 用python处理中文时,读取文件或消息,http参数等等 一运行,发现乱码(字符串处理,读写文件,print) 然后,大多数人的做法是,调用encode/decode进行调试,并没有明确思考为何出现乱码 所以调试时最常出现的错误 错误1 Traceback (most recent call last): File "<stdin>"

学习python处理python编码问题_python

概括.从python1.6开始就可以处理unicode字符了. 一.几种常见的编码格式. 1.1.ascii,用1个字节表示. 1.2.UTF-8,用1个至三个字节表示,表示ascii码时只占用1个字节,ascii编码是UTF-8的子集. 1.3.UTF-16,用2个字节表示,在python中,unicode的含义就是UTF-16. 二.python源文件的编码与解码,我们写的python程序从产生到执行的过程如下: 编辑器---->源代码---->解释器---->输出结果 2.1.编辑

python编码最佳实践之总结

该文章转自阿里巴巴技术协会(ATA) 作者:空溟    相信用python的同学不少,本人也一直对python情有独钟,毫无疑问python作为一门解释性动态语言没有那些编译型语言高效,但是python简洁.易读以及可扩展性等特性使得它大受青睐.      工作中很多同事都在用python,但往往很少有人关注它的性能和惯用法,一般都是现学现用,毕竟python不是我们的主要语言,我们一般只是使用它来做一些系统管理的工作.但是我们为什么不做的更好呢?python zen中有这样一句:There s

Python编码为什么那么蛋疼?

据说,每个做 Python 开发的都被字符编码的问题搞晕过,最常见的错误就是 UnicodeEncodeError.UnicodeDecodeError,你好像知道怎么解决,遗憾的是,错误又出现在其它地方,问题总是重蹈覆辙,str 到 unicode 之间的转换用 decode 还是 encode 方法还特不好记,老是混淆,问题究竟出在哪里? 为了弄清楚这个问题,我决定从 python 字符串的构成以及字符编码的细节上进行深入浅出的分析 字节与字符 计算机存储的一切数据,文本字符.图片.视频.音

Python编码问题整理

认识常见编码   GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码 GBK 是 GB2312的扩展 ,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名 cp936:中文本地系统是Windows中的cmd,默认codepage是CP936,cp936就是指系统里第936号编码格式,即GB2312的编码. (当然有其它编码格式:cp950 繁体中文.cp932 日语.cp1250 中欧语言...) Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案.U

打造自己的 Python 编码环境

前言 趁着放假,重新配置了一下自己的Mac的编程环境,毕竟新年新气象嘛,主要是iTerm2.Zsh.vim 优化.Consolas字体.NoisyTyper,这些的相关配置.工欲利其事必先利其器,好的编码环境可以提升我们的打码的幸福感.好的编码环境包括 美观(视觉),声音(听觉),流畅度(触觉),工作环境(嗅觉,味觉)等多个方面.后面有几张配置后的图片感受一下,主要看字体和配色(有些人可能觉得比 较丑,个人喜欢黑紫,配色和字体有很多选择,各有所好,求别喷 XD). 准备阶段:器 iTerm2:是

python 编码转换 专题

主要介绍了python的编码机制,unicode, utf-8, utf-16, GBK, GB2312,ISO-8859-1 等编码之间的转换. 常见的编码转换分为以下几种情况: 自动识别 字符串编码 可以使用 chardet 模块自动识别 字符创编码 chardet 使用方法 unicode 转换为其它编码(GBK, GB2312等) 例如:a为unicode编码 要转为gb2312.a.encode('gb2312') # -*- coding=gb2312 -*- a = u"中文&qu