python标准库之字符编码详解
codesc官方地址:https://docs.python.org/2/library/codecs.html
相关帮助:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html
#python标准库(英文地址:)http://www.ask3.cn/ebook/docspy3zh/library/index.html
unicode入门:
cpython2.xz支持2种类型字符串处理文本数据,老式的str实例使用单个8位字节表示字符串字符(ascii码),与之不同的unicode串在内部作为一个unicode码点(codepoint)序列来管理,码点值分别保存为2个或者4个字节序列,这取决于编译python时指定的选项,unicode和str都派生一个共同基类,并支持类似的api.
输入unicode串时,会使用某种标准机制编码,使得以后可以将这个字节序列重构为同样的文本串,编码值的字节不一定与码点值完全相同,编码只是定义了在2个值集之间转换的一种方式,读取unocide数据时还需要知道编码,这样才能接到字节转换为unicode类使用内部表示!
西方语言最常用的编码是utf-8 utf-16这2种编码 分别使用单字节和2字节值序列表示各个码点,对于其他语言,由于大多数字符由走过个字节码点表示,所以使用其他编码来存储可能更为高效
#注意:unicode论坛:http://www.unicode.org/ 或者请看<the python unicode howto>书籍信息
#编码
要了解编码,最好的方法就是采用不同方式对相同串进行编码,并查看所生成字节序列的区别
例子:
import binasciidef to_hex(t,nbytpes): item=nbytpes*2 hex1=binascii.hexlify(t) return ' '.join(hex1[s:s+item]for s in xrange(0,len(hex1),item))print to_hex('abcdef',1)print to_hex('abcdef',2)#这个函数使用binascii得到输入字节码的十六进制,在返回这个值之前每隔nbytpes字节就插入一个空格
#第一个编码例子首先使用uncidoe类的原始表示打印文本pi:π,π(3.14)字符替换为unicode码点的表达式\u03c0,接下来使用utf-8 utf-16,得到十六进制text=u'pi:,π'print 'raw :',repr(text)print 'utf-8:{0} and utf-16{1}'.format(to_hex(text.encode('utf-8'),1),to_hex(text.encode('utf-16'),2))#对于一个unicode串编码 的结果是一个str对象
#给定一个编码字节序列(作为一个str实例),decode()方法会将其转换为码点,并作为一个unicode实例返回转换后序列en=text.encode('utf-8')de=en.decode('utf-8')print 'original:',repr(text)print 'en:',to_hex(en,1),type(en)print 'de:',repr(de),type(de)#注意:解释器启动过程中(即加载site时)会设置默认编码,关于默认编码设置的描述,可以参考sys部分(或者文档)
#处理文件
"""处理i/o操作时,编码和解码字符串尤其重要,否认是写入一个文件,一个套接字还是另外一个流,数据都必须使用适当的编码,一般来讲,所有文本数据在读取时都需要从其字节表示解码,写时则需要从内部值 编码为一种特定表示,一种程序可以地编码和解码数据,但是取决于手忙脚乱的编码,是确定是否已读取足够的字节以便充分解码数据,这一点可能并不容易。codes提供了一些类来管理数据的编码和解码,所以应用不需要做这个工作codes提供了最简单的接口可以来替代open()内置函数,新版本函数和内置函数做法相信,不过增加了2个参数来指定编码和所需的错误处理技术"""import sys,codecsen=sys.argv[0]filename=en+'.txt'print 'writing to:',filenamewith codecs.open(filename,mode='wt',encoding=en)as f: f.write(u'pi:\u03c0')n={''utf-8:1,'utf-16':2,'utf-32':4}.get(en,1)print 'file contents:'with open(filename,mode='rt')as f: print to_hex(f.read(),n)#这个例子首先从一个unicode串开始(包括pai的码点),并使用命令行指定指定的编码将文件保存到一个文件中使用open()读取数据很简单,但提前是需要知道它的编码,才能正确的建议解码器,尽管有些数据格式(如;xml)会指定编码作为文件一部分,但是通常都要由应用特定来管理,codecs只是取一个编码参数,并假设这个编码是正确的.
en=sys.argv[0]filename=en+'.txt'print 'writing to:',filename
with codecs.open(filename,mode='wt',encoding=en)as f:
print repr(f.read())
字节顺序
多字节编码utf - 16和utf - 32等问题 不同的计算机系统之间传输数据,通过 直接复制文件或网络通信。 不同的 系统使用不同的排序的高和低字节顺序。 这 数据的特点,被称为它的字节顺序,取决于 等因素的硬件架构和选择 操作系统和应用程序开发人员。 并不总是有一种方法 提前知道使用什么字节顺序对于一个给定的数据集,所以 包括一个多字节编码的字节顺序标记(BOM)的 前几个字节的编码输出。 例如,定义utf - 16 的方式0 xfffe和0 xfeff无效字符,和可以 被用来表示字节顺序。编解码器定义常量 使用的字节顺序标记utf - 16和utf - 32。
for name in [ 'BOM', 'BOM_BE', 'BOM_LE',
'BOM_UTF8',
'BOM_UTF16', 'BOM_UTF16_BE', 'BOM_UTF16_LE',
'BOM_UTF32', 'BOM_UTF32_BE', 'BOM_UTF32_LE',
]:
print '{:12} : {}'.format(name, to_hex(getattr(codecs, name), 2))
取决于当前系统固有字节序,bom,bom_utf16,bom_utf-32会自动设置为适合的大端(big-endian)或者小端(little-endian)值#信息库:
BOM : fffe BOM_BE : feff BOM_LE : fffe BOM_UTF8 : efbb bf BOM_UTF16 : fffe BOM_UTF16_BE : feff BOM_UTF16_LE : fffe BOM_UTF32 : fffe 0000 BOM_UTF32_BE : 0000 feff BOM_UTF32_LE : fffe 0000 可以由codecs中解码器自动检测和处理字节序,不过编码时也可以地指定字节序.#下面这个a.py文件,代码如下:
if codecs.BOM_UTF16 == codecs.BOM_UTF16_BE:
bom = codecs.BOM_UTF16_LE
encoding = 'utf_16_le'
else:
bom = codecs.BOM_UTF16_BE
encoding = 'utf_16_be'
print 'Native order :', to_hex(codecs.BOM_UTF16, 2)
print 'Selected order:', to_hex(bom, 2)
# Encode the text.
encoded_text = u'pi: \u03c0'.encode(encoding)
print '{:14}: {}'.format(encoding, to_hex(encoded_text, 2))
with open('non-native-encoded.txt', mode='wb') as f:
# Write the selected byte-order marker. It is not included in the
# encoded text because we were explicit about the byte order when
# selecting the encoding.
f.write(bom)
# Write the byte string for the encoded text.
f.write(encoded_text)上面a.py这部分代码首先得出内置字节码,然后显示地使用候选形式,以方便下一个例子读取时自动检测字节序.a.py打开文件时没有指定序,所以解码器会使用文件前2个字节中的bom来确定字节序.
with open('non-native-encoded.txt', mode='rb') as f:
raw_bytes = f.read()
print 'Raw :', to_hex(raw_bytes, 2)
# Re-open the file and let codecs detect the BOM
with codecs.open('non-native-encoded.txt', mode='rt', encoding='utf-16') as f:
decoded_text = f.read()
print 'Decoded:', repr(decoded_text)
#由于文件前2个字节用于字节序检测,所以它们并不包含在read()返回数据中
##错误处理
前面几节指出了需要知道的编码 阅读和写作时使用Unicode文件。 设置编码 正确是很重要的,原因有两个。 如果编码配置 错误的同时读取一个文件,数据将被解释 错了,可能会损坏或者无法解码。 并不是所有的Unicode 字符可以用在所有的编码,因此,如果错了 使用编码在写将生成一个错误和数据 是输了。
编解码器使用相同的五个错误处理选项 提供的编码()的方法Unicode和decode()的方法STR。
| strict | Raises an exception if the data cannot be converted.提出了一个异常如果数据不能转换。 |
| replace | Substitutes a special marker character for data that cannot be encoded.替代一个特殊的标记字符数据,不能编码。 |
| ignore | Skips the data.跳过数据。 |
| xmlcharrefreplace | XML character (encoding only)XML字符(编码) |
| backslashreplace | escape sequence (encoding only)转义序列(编码) |
编码错误
最常见的错误条件是收到UnicodeEncodeError当你写 Unicode数据到一个ASCII输出流,如一个常规文件或sys.stdout。 可以使用这个示例程序 尝试不同的错误处理模式。
import codecs
import sys
error_handling = sys.argv[1]
text = u'pi: \u03c0'
try:
# Save the data, encoded as ASCII, using the error
# handling mode specified on the command line.
with codecs.open('encode_error.txt', 'w',
encoding='ascii',
errors=error_handling) as f:
f.write(text)
except UnicodeEncodeError, err:
print 'ERROR:', err
else:
# If there was no error writing to the file,
# show what it contains.
with open('encode_error.txt', 'rb') as f:
print 'File contents:', repr(f.read())要确保一个应用程序地为所有I/O操作设置正确编码,strict模式最安全,但是产生一个异常时,可能导致程序崩溃.
一些其他的错误模式更加灵活。 例如,取代确保没有错误,为代价的 可能失去的数据不能被转换为所请求的 编码。 pi仍不能编码的Unicode字符 ASCII,而是提高异常字符被替换 与吗?在输出。
完全跳过问题数据,使用忽略。 任何数据, 不能编码只是丢弃。 有两种无损的错误处理选项,这两个替换 另一种表示形式的特性定义的标准 独立于编码。xmlcharrefreplace使用XML 作为替代字符引用(字符引用的列表 在W3C中指定吗XML字符实体定义)。 其他无损的错误处理方案backslashreplace哪一个 产生输出格式打印时喜欢你得到的价值repr()的Unicode对象。 Unicode字符 取而代之的是\ u紧随其后的是十六进制值的代码 点。
解码错误
还可以看到错误解码数据时,特别是 使用错误的编码。
error_handling = sys.argv[1]
text = u'pi: \u03c0'
print 'Original :', repr(text)
# Save the data with one encoding
with codecs.open('decode_error.txt', 'w', encoding='utf-16') as f:
f.write(text)
# Dump the bytes from the file
with open('decode_error.txt', 'rb') as f:
print 'File contents:', to_hex(f.read(), 1)
# Try to read the data with the wrong encoding
with codecs.open('decode_error.txt', 'r',
encoding='utf-8',
errors=error_handling) as f:
try:
data = f.read()
except UnicodeDecodeError, err:
print 'ERROR:', err
else:
print 'Read :', repr(data)
与编码,严格的错误处理模式提出了一个例外 如果不能正确解码的字节流。 在这种情况下,UnicodeDecodeError结果 试图将utf - 16 BOM的一部分转换为字符使用 utf - 8解码器。
切换到忽略导致译码器跳过无效 字节。 结果仍然是不期望是什么,不过, 它包括嵌入式空字节。
在取代无效的字节替换模式\ uFFFD, 官方Unicode替换字符,它看起来像一个钻石 包含白色与黑色背景问号(�)。更多请看:http://pymotw.com/2/codecs/ (这个是标准库的)官方地址:https://docs.python.org/2/library/codecs.html
python标准库之字符编码详解的更多相关文章
- (转)python标准库中socket模块详解
python标准库中socket模块详解 socket模块简介 原文:http://www.lybbn.cn/data/datas.php?yw=71 网络上的两个程序通过一个双向的通信连接实现数据的 ...
- Python标准库--time模块的详解
time模块 - - -时间获取和转换 在我们学习time模块之前需要对以下的概念进行了解: 时间戳:时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08 ...
- python标准库介绍——1 os详解
== os 模块 == ``os`` 模块为许多操作系统函数提供了统一的接口. 这个模块中的大部分函数通过对应平台相关模块实现, 比如 ``posix`` 和 ``nt. os`` 模块会在第一次导入 ...
- python标准库中socket模块详解
包含原理就是tcp的三次握手 http://www.lybbn.cn/data/datas.php?yw=71 这篇讲到了socket和django的联系 https://www.cnblogs.co ...
- Python字符编码详解,str,bytes
什么是明文 “明文”是可以是文本,音乐,可以编码成mp3文件.明文可以是图像的,可以编码为gif.png或jpg文件.明文是电影的,可以编码成wmv文件.不一而足. 什么是编码?把明文变成计算机语言 ...
- 转1:Python字符编码详解
Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...
- 转2:Python字符编码详解
1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...
- Python2.7字符编码详解
目录 Python2.7字符编码详解 声明 一. 字符编码基础 1.1 抽象字符清单(ACR) 1.2 已编码字符集(CCS) 1.3 字符编码格式(CEF) 1.3.1 ASCII(初创) 1.3. ...
- Python做简单的字符串匹配详解
Python做简单的字符串匹配详解 由于需要在半结构化的文本数据中提取一些特定格式的字段.数据辅助挖掘分析工作,以往都是使用Matlab工具进行结构化数据处理的建模,matlab擅长矩阵处理.结构化数 ...
随机推荐
- java 截取字符串 拆分字符串
例如 想要吧"90_python" 分成“90” 和“python” 从网上看到的方法: public class splitTest { public static void m ...
- Linux安装WebLogic12
# groupadd weblogic# useradd -g weblogic weblogic# passwd weblogic# mkdir -p /var/bea# chown -R webl ...
- Spring MVC 注解[转]
[学习笔记]基于注解的spring3.0.x MVC学习笔记(九) 摘要: 本章节,仅为@SessionAttributes的功能扩展介绍介绍,结合@requestparam注解进行简易无数据库分页. ...
- 实现C++模板类头文件和实现文件分离的方法
如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer(第四版)>>里的观点:1)标准C++为编译模板代码定义了两种模型:“包含”模型和“ ...
- xml的加密和解密
xml加密(XML Encryption)是w3c加密xml的标准.这个加密过程包括加密xml文档的元素及其子元素,通过加密,xml的初始内容将被替换,但其xml格式仍然被完好的保留. 介绍我们有3个 ...
- ASP.NET获取用户端的真实IP
ASP.NET获取用户端的真实IP在各种场景都能用到,但是用户网端变幻莫测情况众多,获取真实IP还真是不容易啊.下面分享个比较好一点的方法: 获取IP初始版本 /// <summary> ...
- java基础之导入(药师点评)
/** * 药师点评的导入 * @param request * @param response * @param f * @param tmallTcMessageImport * @return ...
- 前端 JavaScript基础
前言 JavaScript 是属于网络的脚本语言,被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用. 一.如何编写 1.存在形式 方式一:存在js文件中,即写入j ...
- MVC,jquery异步
创建一个Ajax控制器 using System; using System.Collections.Generic; using System.Linq; using System.Web; usi ...
- (转)检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(转)
我们将ASP.NET程序从IIS6移植到IIS7,可能运行提示以下错误: HTTP 错误 500.23 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.N ...