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 实现插入排序算法
Jun 05 Python
Python实现远程调用MetaSploit的方法
Aug 22 Python
python中使用xlrd、xlwt操作excel表格详解
Jan 29 Python
将Python的Django框架与认证系统整合的方法
Jul 24 Python
python实现windows下文件备份脚本
May 27 Python
python中reader的next用法
Jul 24 Python
Python简单I/O操作示例
Mar 18 Python
Python3.7下安装pyqt5的方法步骤(图文)
May 12 Python
Pytorch环境搭建与基本语法
Jun 03 Python
Keras SGD 随机梯度下降优化器参数设置方式
Jun 19 Python
vscode调试django项目的方法
Aug 06 Python
解决Pytorch dataloader时报错每个tensor维度不一样的问题
May 28 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
PHP内核探索:变量概述
2014/01/30 PHP
php 判断网页是否是utf8编码的方法
2014/06/06 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
2019/09/11 PHP
Aster vs KG BO3 第三场2.19
2021/03/10 DOTA
一个用javascript写的select支持上下键、首字母筛选以及回车取值的功能
2009/09/09 Javascript
JQuery 自定义CircleAnimation,Animate方法学习笔记
2011/07/10 Javascript
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
判定是否原生方法的JS代码
2013/11/12 Javascript
javascript轻量级模板引擎juicer使用指南
2014/06/22 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
JavaScript中的原型prototype属性使用详解
2015/06/05 Javascript
快速使用Bootstrap搭建传送带
2016/05/06 Javascript
在javascript中创建对象的各种模式解析
2016/05/16 Javascript
Web安全测试之XSS实例讲解
2016/08/15 Javascript
javascript 封装Date日期类实例详解
2017/05/28 Javascript
利用JS做网页特效_大图轮播(实例讲解)
2017/08/09 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
JavaScript函数、闭包、原型、面向对象学习笔记
2018/09/06 Javascript
JS相册图片抖动放大展示效果的示例代码
2021/01/29 Javascript
[02:32]DOTA2完美大师赛场馆静安体育中心观赛全攻略
2017/11/08 DOTA
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python中查看文件名和文件路径
2017/03/31 Python
python之生成多层json结构的实现
2020/02/27 Python
webView加载html图片遇到的问题解决
2019/10/08 HTML / CSS
美国护肤咨询及美容产品电商:Askderm
2017/02/24 全球购物
介绍一下HDLC(High-Level Data Link Control)高层数据链路协议
2012/01/21 面试题
关于逃课的检讨书
2014/01/23 职场文书
总经理岗位职责说明书
2014/07/30 职场文书
2015年后勤工作总结范文
2015/04/08 职场文书
爱心捐助活动总结
2015/05/09 职场文书
债务纠纷代理词
2015/05/25 职场文书
一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的
2021/05/25 MySQL
手把手教你怎么用Python实现zip文件密码的破解
2021/05/27 Python
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python
python异步的ASGI与Fast Api实现
2021/07/16 Python
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS