PYTHON编码处理-str与Unicode的区别


一篇关于str和Unicode的好文章


整理下python编码相关的内容

注意: 以下讨论为Python2.x版本, Py3k的待尝试


开始

用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文档

入口



好了,暂时就这么多,希望讲清楚了

thx

wklken

2013-08-31 于深圳


版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

如果你觉得我的文章或项目对你有所帮助, You can buy me a coffee:)

时间: 2024-08-08 01:27:29

PYTHON编码处理-str与Unicode的区别的相关文章

Python中的str与unicode处理方法

Python中的str与unicode处理方法 2015/03/25 · 基础知识 · 3 评论· Python 分享到:42 原文出处: liuaiqi627 的博客 python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自己总结一篇文章. 我也会在以后学习中,不断的修改此篇博客. 这里假设读者已有与编码相关的基础知识,本文不再再次介绍,包括什么是utf-8,什么是unicode,它们之间有什么关系. str与字节码 首先,我们完全不谈u

[转]Python中的str与unicode处理方法

早上被python的编码搞得抓耳挠腮,在搜资料的时候感觉这篇博文很不错,所以收藏在此. python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自己总结一篇文章. 我也会在以后学习中,不断的修改此篇博客. 这里假设读者已有与编码相关的基础知识,本文不再再次介绍,包括什么是utf-8,什么是unicode,它们之间有什么关系. str与字节码 首先,我们完全不谈unicode. s = "人生苦短" s是个字符串,它本身存储的就是字节

Python 编码,str,bytes

什么是明文 "明文"是可以是文本,音乐,可以编码成mp3文件.明文可以是图像的,可以编码为gif.png或jpg文件.明文是电影的,可以编码成wmv文件.不一而足. 什么是编码?把明文变成计算机语言 为什么要用Unicode来编码?可以记录所有语言,而且编码方式不止一种 python str与bytes之间的转换 # bytes object b = b"example" # str object s = "example" # str to b

python中的str,unicode和gb2312

实例1: v1=u '好神奇的问题!?' type(v1)->unicode v1.decode("utf-8")# not work,because v1 is unicode already v1.encode("gb2312")#work,convert from unicode into gbk2312 [发现] decode是把指定的对象转化为unicode(unicode包含utf-8,utf-16),并且指明了待转化对象的编码方式. encode

【转】Python——编码规范

来自于 啄木鸟社区 Python Coding Rule --- hoxide 初译 dreamingk 校对发布 040724 --- xyb 重新排版 040915 --- ZoomQuiet MoinMoin 美化 050610 用Python进行开发时的编码风格约定 原文:PEP 008 <Style Guide for Python Code> 下载(中文pdf): PythonCodingRule.pdf 进一步的: Google Python Style Guide Python

python 编码问题

字符串在Python内部的表示是unicode 编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码. decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码. encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb

python 字符串编码 str和unicode 区别以及相互转化 decode(&#39;utf-8&#39;) encode(&#39;utf-8&#39;)

python 字符串编码 str和unicode 区别以及相互转化 decode('utf-8') encode('utf-8') 原文地址:https://www.cnblogs.com/zhaoyingjie/p/9133020.html

Python中GBK, UTF-8和Unicode的编码问题

编码问题,一直是使用python2时的一块心病.几乎所有的控制台输入输出.IO操作和HTTP操作都会涉及如下的编码问题: UnicodeDecodeError:‘ascii’codec can’t decodebyte0xc4inposition10:ordinalnotinrange(128) 这究竟是是个什么东西?!有时稀里糊涂地用一坨encode(),decode()之类的函数让程序能跑对了,可是下次遇到非ASCII编码时又悲剧了. 那么Python 2.x中的字符串究竟是个什么呢? 基本

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

最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下笔记.方便以后查阅和大家学习. 中文编码问题的处理核心都是--保证所有的编码方式一致即可,包括编译器.数据库.浏览器编码方式等,而Python通常的处理流程是将unicode作为中间转换码进行过渡.先将待处理字符串用unicode函数以正确的编码转换为Unicode码,在程序中统一用Unicode字