【Python】Python编码和Unicode
2015-12-14 17:14
615 查看
Python编码和Unicode
字节流 vs Unicode对象
我们先来用Python定义一个字符串。当你使用string类型时,实际上会储存一个字节串。ASCII是用前127个数字来做字符映射。像windows-1252和UTF-8这样的字符映射有相同的前127个字符。在你的字符串里每个字节的值低于127的时候是安全的混合字符串编码。然而作这个假设是件很危险的事情,下面还将会提到。
当你的字符串里有字节的值大于126的时候就会出现问题了。我们来看一个用windows-1252编码的字符串。Windows-1252里的字符映射是8位的字符映射,那么总共就会有256个字符。前127个跟ASCII是一样的,接下来的127个是由windows-1252定义的其他字符。
解码字节流
在一开始学习Python Unicode 的时候,解码这个术语可能会让人很疑惑。你可以把字节流解码成一个Unicode对象,把一个Unicode 对象编码为字节流。Python需要知道如何将字节流解码为Unicode对象。当你拿到一个字节流,你调用它的“解码方法来从它创建出一个Unicode对象。
你最好是尽早的将字节流解码为Unicode。
将Unicode编码为字节流
Unicode对象是一个文本的编码不可知论的代表。你不能简单地输出一个Unicode对象。它必须在输出前被变成一个字节串。Python会很适合做这样的工作,尽管Python将Unicode编码为字节流时默认是适用ASCII,这个默认的行为会成为很多让人头疼的问题的原因。str_string.decode('codec') 是把str_string转换为unicode_string, codec是源str_string的编码方式
unicode_string.encode('codec') 是把unicode_string 转换为str_string,codec是目标str_string的编码方式
str_string.decode('from_codec').encode('to_codec') 可实现不同编码的str_string之间的转换
比如:
>>> t='长城'
>>> t
'\xb3\xa4\xb3\xc7'
>>> t.decode('gb2312').encode('utf-8')
'\xe9\x95\xbf\xe5\x9f\x8e'
str_string.encode('codec') 是先调用系统的缺省codec去把str_string转换为unicode_string,然后用encode的参数codec去转换为最终的str_string. 相当于str_string.decode('sys_codec').encode('codec')。
unicode_string.decode('codec') 基本没有意义,unicode 在python里只用一种unicode编码,UTF16或者UTF32(编译python时就已经确定),没有编码转换的需要。
注:缺省codec在site-packages下的sitecustomize.py文件中指定,比如
import sys
sys.setdefaultencoding('utf-8')
使用codecs模块
codecs模块能在处理字节流的时候提供很大帮助。你可以用定义的编码来打开文件并且你从文件里读取的内容会被自动转化为Unicode对象。试试这个:
试试这个:
当从一个文件读取数据的时候,codecs.open 会创建一个文件对象能够自动将utf-8编码文件转化为一个Unicode对象。
我们接着上面的例子,这次使用urllib流。
将UTF-8字节流切片的问题
因为一个UTF-8编码串是一个字节列表,len( )和切片操作无法正常工作。首先用我们之前用的字符串。为了正确的切分UTF-8,你最好是解码字节流创建一个Unicode对象。然后就能安全的操作和计数了。
当Python自动地编码/解码
在一些情况下,当Python自动地使用ASCII进行编码/解码的时候会抛出错误。第一个案例是当它试着将Unicode和字节串合并在一起的时候。
在这个例子里面,你创建一个utf-8文件,然后往里面添加一些Unicode对象的文本。就会报UnicodeDecodeError错误。
最佳实践
1.最先解码,最后编码2.默认使用utf-8编码
3.使用codecs和Unicode对象来简化处理
最先解码意味着无论何时有字节流输入,需要尽早将输入解码为Unicode。这会防止出现len( )和切分utf-8字节流发生问题。
最后编码意味着只有你打算将文本输出到某个地方时,才把它编码为字节流。这个输出可能是一个文件,一个数据库,一个socket等等。只有在处理完成之后才编码unicode对象。最后编码也意味着,不要让Python为你编码Unicode对象。Python将会使用ASCII编码,你的程序会崩溃。
默认使用UTF-8编码意味着:因为UTF-8可以处理任何Unicode字符,所以你最好用它来替代windows-1252和ASCII。
codecs模块能够让我们在处理诸如文件或socket这样的流的时候能少踩一些坑。如果没有codecs提供的这个工具,你就必须将文件内容读取为字节流,然后将这个字节流解码为Unicode对象。
codecs模块能够让你快速的将字节流转化为Unicode对象,省去很多麻烦。
解释UTF-8
最后的部分是让你能对UTF-8有一个入门的了解,如果你是个超级极客可以无视这一段。利用UTF-8,任何在127和255之间的字节是特别的。这些字节告诉系统这些字节是多字节序列的一部分。
那么完整的字节序列。
相关文章推荐
- python培训Day8 随笔
- python安装mysqldb
- Python中yield
- 分享一道伯克利 CS 61A 关于高阶函数的一道Python作业题(2)
- python日志logging模块学习
- Python基本内置数据类型有哪些?
- 【Python】利用count函数求list中每个元素出现的次数,求众数的改进
- 测试开发Python培训:模拟登录新浪微博-技术篇
- python之记录一次内存泄露
- 数据科学家必知必会的7款Python工具,你会几个?
- 我的第一个基于python的socket程序
- 大数据全栈式开发语言——Python
- python基础教程共60课-第40课用文件保存游戏2
- 测试开发Python培训:模拟登录新浪微博-技术篇 2
- 测试开发Python培训:模拟登录新浪微博-技术篇
- 测试开发Python培训:抓取新浪微博抓取数据-技术篇
- 通过python构建集中式的病毒扫描机制
- 【python】python实例集<二>
- python基础教程共60课-第39课用文件保存游戏1
- 用python在hadoop上运行wordcount