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


Posted in Python onSeptember 06, 2016

一篇关于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 编码处理的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!

Python 相关文章推荐
python实现根据图标提取分类应用程序实例
Sep 28 Python
Python中优化NumPy包使用性能的教程
Apr 23 Python
Python中使用asyncio 封装文件读写
Sep 11 Python
Python遍历文件夹和读写文件的实现方法
May 10 Python
Python有序字典简单实现方法示例
Sep 28 Python
Python使用SQLite和Excel操作进行数据分析
Jan 20 Python
python编写暴力破解zip文档程序的实例讲解
Apr 24 Python
Python实现常见的回文字符串算法
Nov 14 Python
Python中那些 Pythonic的写法详解
Jul 02 Python
python3 实现的对象与json相互转换操作示例
Aug 17 Python
Python 安装 virturalenv 虚拟环境的教程详解
Feb 21 Python
python绘制云雨图raincloud plot
Aug 05 Python
Python如何获取系统iops示例代码
Sep 06 #Python
python3编码问题汇总
Sep 06 #Python
用Python实现命令行闹钟脚本实例
Sep 05 #Python
Python爬虫爬取美剧网站的实现代码
Sep 03 #Python
Python选课系统开发程序
Sep 02 #Python
简单谈谈Python中函数的可变参数
Sep 02 #Python
Python实现自动添加脚本头信息的示例代码
Sep 02 #Python
You might like
开启CURL扩展,让服务器支持PHP curl函数(远程采集)
2011/03/19 PHP
使用php检测用户当前使用的浏览器是否为IE浏览器
2013/12/03 PHP
php实现的简单日志写入函数
2015/03/31 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
Javascript写了一个清除“logo1_.exe”的杀毒工具(可扫描目录)
2007/02/09 Javascript
使用新的消息弹出框blackbirdjs
2008/10/16 Javascript
在chrome中window.onload事件的一些问题
2010/03/01 Javascript
jquery实现弹出div,始终显示在屏幕正中间的简单实例
2014/03/08 Javascript
js验证IP及子网掩码的合法性有效性示例
2014/04/30 Javascript
JavaScript立即执行函数的三种不同写法
2014/09/05 Javascript
Node.js实现批量去除BOM文件头
2014/12/20 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
jQuery+CSS3实现3D立方体旋转效果
2015/11/10 Javascript
jquery实现无刷新验证码的简单实例
2016/05/19 Javascript
bootstrap中使用google prettify让代码高亮的方法
2016/10/21 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
javascript中的闭包概念与用法实践分析
2019/07/26 Javascript
Vue 根据条件判断van-tab的显示方式
2020/08/03 Javascript
解决ant Design Search无法输入内容的问题
2020/10/29 Javascript
python实现socket端口重定向示例
2014/02/10 Python
Python解释执行原理分析
2014/08/22 Python
python实现比较两段文本不同之处的方法
2015/05/30 Python
Python使用lxml模块和Requests模块抓取HTML页面的教程
2016/05/16 Python
Python、PyCharm安装及使用方法(Mac版)详解
2017/04/28 Python
Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例
2018/03/15 Python
Python实现计算长方形面积(带参数函数demo)
2020/01/18 Python
法国购买隐形眼镜和眼镜网站:Optical Center
2019/10/08 全球购物
No7 Beauty美国官网:英国国民护肤品牌
2019/10/31 全球购物
地质灾害防治方案
2014/05/14 职场文书
个人自我剖析材料
2014/09/30 职场文书
中学团支部工作总结
2015/08/13 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
子女赡养老人协议书
2016/03/23 职场文书
Python爬虫:从m3u8文件里提取小视频的正确操作
2021/05/14 Python
Python万能模板案例之matplotlib绘制甘特图
2022/04/13 Python