学Python以来,遇到不少关于编码方面的问题,总是知其然不知其所以然,糊里糊涂的。今天在邮件列表中看到甘晖问一个编码的问题,有不少高手解释。看了以后霍然开朗,记录一下,以后备查:)

一、(以下为张骏的解释,感谢)
个人认为python对unicode的处理已经相当完善了。

对于python来讲,字符集的处理有两个概念:
1  str            是指带有编码的字符串
2  unicode  是指不带有编码的字符串

这两个概念的相互转换是这样进行的:
str ------>   unicode --------> str
   decode             encode
   解码                    编码

举个最简单的例子:

>>> a = '中'
>>> a
'/xd6/xd0'

>>> b = u'中'
>>> b
u'/u4e2d'

根据上面的描述,b应该是不进行编码的a的值(反正a就是b带有gbk编码的值)
于是,我们可以得到
>>> a.decode( 'gbk' )
u'/u4e2d'

同样也可以得到
>>> b.encode( 'gbk' )
'/xd6/xd0'

不知道我讲的清楚吗?

另外,甘晖遇到的这个xml解析的问题并不是python对编码集处理的问题。而是python的xml模块pyexpat.pyd不支持非utf-8编码的多字节xml的原因。为什么不支持,是因为xml的标准规范仅仅定义了utf-8做为多字节xml的编码,gbk(gb2312)并不是xml规范中允许的字符集。

因此,我们在处理gbk编码集的xml时,都是先将文件读取出来,然后转换为utf8格式,然后再解析
>>> f = file( r'c:/a.xml' )
>>> buf = f.read()
>>> ubuf = buf.decode( 'gbk' ).encode( 'utf-8' )
>>> xml.parser( ubuf )
...

调用字符串的decode和encode方法有一个好处是,不用显式import codecs模块,更不用lookup特定字符编码的decode和encode函数。但是这种方法不适用于对decode和encode方法多次重复调 用的场合,主要是从代码的执行效率方面考虑的。(这一段是 麦田守望者的意见)

二、(以下摘自麦田守望者的blog,感谢)

使用codecs模块,在Python中完成字符编码
字符的编码是按照某种规则在单字节字符和多字节字符之间进行转换的某种方法。从单字节到多字节叫做decoding,从多字节到单字节叫做encoding。在这些规则中经常用到的无非是UTF-8和GB2312两种。
 
在Python中,codecs模块提供了实现这些规则的方法,通过模块公开的方法我们能够方便地获取某种编码方式的Encoder和 Decoder工厂函数(Factory function),以及StreamReader、StreamWriter和StreamReaderWriter类。
 
使用“import codecs”导入codecs模块。
 
codecs模块中重要的函数之一是lookup,它只有一个参数encoding,指的是编码方式的名称,即utf-8或者gb2312等等。如下示例:

>>> import codecs
>>> t = codecs.lookup("utf-8")
>>> print t
(<built-in function utf_8_encode>, <function decode at 0x00AA25B0>, <class encodings.utf_8.StreamReader at 0x00AA0720>, <class encodings.utf_8.StreamWriter at 0x00AA06F0>)
>>> encoder = t[0]
>>> decoder = t[1]
>>> StreamReader = t[2]
>>> StreamWriter = t[3]

lookup函数返回一个包含四个元素的TUPLE,其中T[0]是encoder的函数引用,T[1]是decoder的函数引用,T[2] 是UTF-8编码方式的StreamReader类对象引用,T[3]是UTF-8编码方式的StreamWriter类对象引用相信对Python熟悉 的你肯定知道接下来该怎么用它们了。
 
codecs模块还提供了方便程序员使用的单独函数,以简化对lookup的调用。它们是:
  • getencoder(encoding)
  • getdecoder(encoding)
  • getreader(encoding)
  • getwriter(encoding)
如果我们只是想获取一种utf-8编码的encoder方法,那么只需要这样做:

>>> encoder = codecs.getencoder("utf-8")

 
另外,对于StreamReader和StreamWriter的简化, codecs模块提供一个open方法。相对于built-in对象File的open方法,前者多了三个参数encoding, errors, buffering。这三个参数都是可选参数,但是对于应用来说,需要明确指定encoding的值,而errors和buffering使用默认值即 可。使用方法如下:

>>> fin = codecs.open("e://mycomputer.txt", "r", "utf-8")
>>> print fin.readline()
这是我的电脑
>>> fin.close()

 
总结一下,codecs模块为我们解决的字符编码的处理提供了lookup方法,它接受一个字符编码名称的参数,并返回指定字符编码对应的 encoder、decoder、StreamReader和StreamWriter的函数对象和类对象的引用。为了简化对lookup方法的调用, codecs还提供了getencoder(encoding)、getdecoder(encoding)、getreader(encoding)和 getwriter(encoding)方法;进一步,简化对特定字符编码的StreamReader、StreamWriter和 StreamReaderWriter的访问,codecs更直接地提供了open方法,通过encoding参数传递字符编码名称,即可获得对 encoder和decoder的双向服务。
-----------------------------------------------

PS:对Python里面的编码总算有个比较清楚的认识了,为了避免麻烦,自己写程序好文件的时候,都在前面加上# -*- coding: utf-8 -*-为好。

重要补记(二零零六年九月七日下午):

一、上面的例子请在命令行下测试,在IDLE下有些会有错误!!我已经决定再也不用IDLE了,太痛苦了,debug半天才发现是IDLE的bug!!

二、刚才用C扩展Python,发现在Python里面传一个字符串给C,在C中打印,如果其中有中文字符,就会有乱码。(如果你没有在文件中加# -*- coding: utf-8 -*-,就不会有这个问题)

解决方法如下:

s  =  u " 欢迎使用rss阅读器 "
s = s.encode( ' gbk ' )                       
libConsole.ConsoleOutput(s)    # libConsole是用C封装成的一个dll,
                                                       # ConsoleOutput(s) 是用C写的一个方法,就是
                                                        #一个printf语句

菜鸟学Python(4):编码问题相关推荐

  1. python语言入门教程-菜鸟学Python入门教程大盘点|7个多月的心血总结

    原标题:菜鸟学Python入门教程大盘点|7个多月的心血总结 阅读本文大概需要5分钟 菜鸟学python已经写了70几篇,入门的教程已经快写完了,我把入门的文章整理了一下,下面是入门篇的一些总结,也是 ...

  2. python入门教程(非常详细)-菜鸟学Python入门教程大盘点|7个多月的心血总结

    原标题:菜鸟学Python入门教程大盘点|7个多月的心血总结 阅读本文大概需要5分钟 菜鸟学python已经写了70几篇,入门的教程已经快写完了,我把入门的文章整理了一下,下面是入门篇的一些总结,也是 ...

  3. 菜鸟能学python编程,菜鸟学Python编程文章阅读记录一

    菜鸟学Python编程文章阅读记录 看的懵懵懂懂,感觉就是要把代码看懂到,这个代码块做了什么功能,了解到建了属性,定义了方法,这些方法与属性的关系 今天是js逆向专题,这个帖子,回头再好好看 回头再找 ...

  4. python数据分析相关论文_菜鸟学Python|数据分析精华文章大集合

    原标题:菜鸟学Python|数据分析精华文章大集合 这是菜鸟学Python的第123篇原创文章 Python的数据分析是我比较喜欢的一个方向,因为可以探索数据里面的秘密,加上可视乎会非常漂亮,但是里面 ...

  5. python菜鸟入门_值得收藏|菜鸟学Python【入门文章大全】

    这是菜鸟学Python的第106篇原创文章 阅读本文大概需要3分钟 菜鸟学python已经写了好多好多文章,我自己也没有想到能写这么多累计已经有110篇了,从入门篇写到了数据篇. 我觉得还有好多绝招, ...

  6. 菜鸟学Python(2):学而不思则罔(从一个Python Bug谈开)

    菜鸟学Python(2):学而不思则罔                                                                   ---温铭    http: ...

  7. python语言type board_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题……...

    针对Python这一话题每天后台都会有不少小伙伴提出问题,下面我就将这些问题进行汇整,产出"Python实战问题篇",我认为这些问题非常具有代表性,希望可以帮到大家. 第一类问题: ...

  8. python wx窗口无法关闭_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题…...

    针对Python这一话题每天后台都会有不少小伙伴提出问题,下面我就将这些问题进行汇整,产出"Python实战问题篇",我认为这些问题非常具有代表性,希望可以帮到大家. 第一类问题: ...

  9. 小菜鸟学Python记

    菜鸟原本是做城市规划的,对城市空间的大数据分析一直有所向往 后来参与城市更新政策研究,也需要通过数据手段去收集行业信息和分析人群行为 2019年前后,听闻有个Python技术很厉害,可以爬取全网的信息 ...

最新文章

  1. 【摩天好课推荐】传统企业数字化转型的困惑、思考与实践
  2. android游戏开发框架libgdx的使用(二十四)—physics-body-editor配合Box2D加快开发
  3. matlab组织的培训讲义,matlab培训讲义.doc
  4. netflix_Netflix播放按钮剖析
  5. python控制其它软件_从另一个脚本控制python脚本
  6. 初识spring-boot
  7. WIN2003设完C盘权限后终端连不上。
  8. pix2pix, CycleGAN和pix2pixHD(没有公式,容易理解)
  9. Skywalking-02:如何写一个Skywalking trace插件
  10. 测试kafka的连通性,自导自演生产者与消费者
  11. 图片相框展示的设计与实现
  12. 预约直播!抢CSDN纪念卫衣:开源是在为爱发电?
  13. [转载] python判断字符串中包含某个字符串_干货分享| Python中最常用的字符串方法
  14. 真不知道起什么名字了
  15. 进阶:案例三: Upload File using WebDynpro
  16. 回归预测 基于ELMAN递归神经网络预测及其matlab代码实现
  17. The Productive Programmer 读书笔记
  18. 如何使用Arduino 舵机SG90
  19. c语言常用逻辑符号,C语言常用逻辑符号.doc
  20. 几何平均数与AG不等式

热门文章

  1. 【甘道夫】Win7x64环境下编译Apache Hadoop2.2.0的Eclipse小工具
  2. mysql boolean类型_mysql 布尔类型
  3. 折叠屏”今年手机市场的主题
  4. forever 中文解释
  5. forever 管理node服务
  6. python儿童画教程_儿童节教你用 Python 画出童年回忆
  7. 【转载】odoo技术开发白皮书 前言
  8. 阅读论文的方法和技巧
  9. 上交大网安研究研究方向介绍
  10. 转:云计算合同中需要注意的十大关键条款