开始

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

PYTHON-进阶-编码处理小结相关推荐

  1. unicode 编码转换漏洞_好程序员Python教程之字符串编码知识小结

    好程序员Python教程之字符串编码知识小结,提及Python字符串,你会想到什么?是ASCII,还是Unicode?他们之间是如何转换的?字符串编码和字符串有什么区别?接下来好程序员Python教程 ...

  2. python编码转换语句_好程序员Python教程之字符串编码知识小结

    好程序员Python教程之字符串编码知识小结,提及Python字符串,你会想到什么?是ASCII,还是Unicode?他们之间是如何转换的?字符串编码和字符串有什么区别?接下来好程序员Python教程 ...

  3. python进阶10 MySQL补充 编码、别名、视图、数据库修改

    python进阶10 MySQL补充    编码.别名.视图.数据库修改 一.编码问题 #MySQL级别编码 #修改位置: /etc/mysql/mysql.conf.d/mysqld.cnf def ...

  4. Python 进阶之路 (九) 再立Flag, 社区最全的itertools深度解析(上)

    前言 大家好,今天想和大家分享一下我的itertools学习体验及心得,itertools是一个Python的自带库,内含多种非常实用的方法,我简单学习了一下,发现可以大大提升工作效率,在sf社区内没 ...

  5. Python 进阶_生成器 生成器表达式

    目录 目录 相关知识点 生成器 生成器 fab 的执行过程 生成器和迭代器的区别 生成器的优势 加强的生成器特性 生成器表达式 生成器表达式样例 小结 相关知识点 Python 进阶_迭代器 & ...

  6. 转载、Python的编码处理(二)

    以下转自于:wklken的博客,写的非常好的一段有关编码的总结. Python-进阶-编码处理小结 整理下python编码相关的内容 注意: 以下讨论为Python2.x版本, Py3k的待尝试 开始 ...

  7. [转载] Python进阶:设计模式之迭代器模式

    参考链接: Python中的迭代器 在软件开发领域中,人们经常会用到这一个概念--"设计模式"(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一 ...

  8. python进阶20装饰器

    原创博客地址:python进阶20装饰器 Nested functions Python允许创建嵌套函数,这意味着我们可以在函数内声明函数并且所有的作用域和声明周期规则也同样适用. 1 2 3 4 5 ...

  9. python进阶06并发之二技术点关键词

    原创博客地址:python进阶06并发之二技术点关键词 GIL,线程锁 python中存在GIL这个"线程锁", 关键地方可以使用c语言解决 GIL问题 然后可以提高cpu占用效率 ...

  10. 学习Python全套代码【超详细】Python入门、核心语法、数据结构、Python进阶【致那个想学好Python的你】

    大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师.欢迎大家跟我一起走进数据分析的世界,一起学习! 感兴趣的朋友可以关注我的数据分析专栏,里面有许多优质的文章跟大家分享哦. 文末附上详细的 ...

最新文章

  1. linux防火墙添加端口并开闭防火墙
  2. Qt for ios 设置程序显示名称
  3. Android构建流程——篇二
  4. 超全的Android组件及UI框架
  5. Java的不同进制输出,[DanoR][Java小码][进制转换::将double转换为不同进制后用String输出]...
  6. Fix My iPhone Mac版:修复iPhone白苹果、黑屏、卡住恢复错误等iOS 15 升级失败
  7. 在.NET环境中实现每日构建(Daily Build)--ccnet,MSBuild篇
  8. URL.createObjectURL图片预览
  9. 利用SQL语言修正与撤销数据库
  10. 下发布可执行文件_IOS APP 发布过程中涉及相关概念
  11. 导出数据库数据生成word【2】--itext直接写word中写入内容
  12. 去除 火狐浏览器自动给域名前加 www.
  13. mysql 嵌套_MySQL嵌套查询实例详解
  14. Web自动化测试:超详细的环境搭建步骤
  15. 2022微服务面试题 最新50道题(含答案解析)
  16. AutoResetEvent和ManualResetEvent对比
  17. Deepin 与 Win10 双系统 Deepin无法启动且没有引导项问题
  18. 关于win10中资源管理器卡顿的问题及解决办法
  19. 怎样设置电脑宽带连接无线路由器设置路由器连接服务器,电脑设置无线路由器断线后自动连接的方法...
  20. ​mybatis collection解析以及和association的区别

热门文章

  1. 鸿蒙系统的挑战,简单的讲解下何为鸿蒙系统,可能会挑战你的认知颠覆你的想象...
  2. php strpos无效,簡單的PHP strpos功能不起作用,為什么?
  3. 计算机应用能力文字录入,2017全国专业技术人员计算机应用能力考试题库-Excel,Word,XP.pdf...
  4. h3c 链路聚合测试_良无磐石固,虚名复何益?- 链路聚合协议互通测试
  5. AndroidStudio cmakelist找不到问题
  6. C++中使用流读取数据 ifstream
  7. 2M线路保护实现与应用
  8. 哪些原因会导致rs485转换器信号受干扰?
  9. [渝粤教育] 西南科技大学 投资经济学 在线考试复习资料(2)
  10. 物联网在医疗保健中的应用