Contents
实例故事
~ Realy Taste Storys
- 笔者自2000年通过自学PHP,从而进入自由软件世界接触到Python,到2004年参与啄木鸟Python社区,2005参与创立CPyUG,对 Python 的兴趣和信心是一直增长着的; 但发觉世人对这一优秀语言的认知非常非常有限,即使各个综合技术社区中已经出现Python板块,又甚或 Google 公司的成功,都没有促动起Python在中国都的发展;
- 这才开始思考 Python 的推广,反思自个儿的 Python 学习体验,寻找是否有更加轻松的学习方式以及好书来促进Python 在中国落地生根;再后来通过对社会化学习方面的体验,意识到:
学习的阶级
- 从低到高应该是:
不知己不知 < 不知己知 < 知己知 < 知己不知
- 为什么这么说?
开始涉及一个全新技术领域时,我们不知道我们对这个领域的任何信息,也就是连不知道什么都没有概念;
- 后来,通过不自觉的下意识的信息接收,或是主动的学习,获得了部分相关信息,但是从来没有考虑使用这领域的知识来解决问题,所以,不知道自个儿已经知道了哪些领域内的实用信息;
- 再后来,通过实践,切实掌握了领域的基础知识,并对领域内的所有方面都有所了解,明确在领域内自个儿掌握了什么;好比举着油灯进在一个大图书馆中,刚好照亮了周围几排书架,但是不清楚在光圈以外还有多少书架;
- 最后,推而广之,对领域相关的所有知识领域都有所了解,掌握了领域间的关系,明白自个儿究竟还有多少知识不知道;好比那个大图书馆中,打开了所有的电灯,明白自个儿身边这一整书架同整个图书馆其它书架的关系;
感觉,只有快速达到知己知的阶段,才可能事半功倍的高效率/自信/自觉的继续学习下去;
- 幸好,Python 真的的确是个易学好用的语言,怎么向其它没有摸到 Python 秉性的人们宣传这种体验呢?
- developerWorks 中 David Mertz 创作的“可爱的 Python”系列 :
也就成为本书的原型结构了:
将 Python 最可爱的方面,以小篇幅的轻松形式组织发布出来!
接下来就是两个以解决实际问题为出发点,有剧情有人物的,模拟真实事件发展而记述的,一个小白的成长故事. 希望读者可以跟随小白轻松体验到 Pythonic
CDay -1 实用化,中文!
~ 中文处理完成功能的实用化
你能够碰到的问题,99%的情况下其它人已经遇到过了,所以,最佳的解决方式就是找到那段别人解决相似问题的代码!
回顾需求
小白已经实现的需求已经到达这般了:
- 可以扫描光盘内容并存储为硬盘上的文本文件
- 存储成*.cdc 的文本文件
- 可以快速指定保存目录
- 可以快速指定保存的文件名
- 可以根据储存到硬盘上的光盘信息进行搜索
- 可以搜索指定目录中所有*.cdc文件
- 可以指定关键字进行搜索
- 列出所有含有关键字的信息行
进一步
回想起来一直尝试搜索的都是E文关键字,中文的没有试过;
尝试来几下! ... 呜乎矣哉,什么也查不出来!
查阅记录文本
图 CDay-1-1 mymusic-1.cdc内容
这种数据对嘛?
- 当初为了简单使用文档中的基本型:
#'cdctools.py' 中 cdWalker(cdrom,cdcfile) 的动作 ... for root, dirs, files in os.walk(cdrom): export+="\n %s;%s;%s" % (root,dirs,files) ...
就是使用 os.walk() 的天然输出组织成每一行:
/media/cdrom0/EVA/Death-Rebirth;[];['eva8-01.Mp3', 'eva8-02.Mp3',...] ^ ^ ^ ^ | | | +- files列表,此目录的文件名 | | +- 各个数据段使用";" 分隔 | +- dirs列表,子目录名,如果没有就为空 +- 当前目录
- 瞧着格式象,为什么到中文的地方就是问号呢?
中文!永远的痛
不问不知道,一把辛酸泪哪...
- 在网络中一搜索才知道,只要是个中国人,不论整什么开发,中文!永远会遇到各种问题的
- 幸好比小白勤劳的人海了去,有关中文的Python 处理也是一搜一大堆
但是!有时候,选择太多也是个问题;-)
编码问题
图 CDay-1-2 编码思维图谱
有行者给出如上思维图谱(Mind Map)
- 理解过程中,先使用已知的方式测试本地硬盘文件目录情况
图 CDay-1-3 本地文件目录测试结果
- 嗯嗯嗯,看着就不同,根据理解继续尝试是否理解
图 CDay-1-4 另一些测试结果(使用unicode)
unicode(原始文本, 'utf8' ).encode('utf8') 文本==>decode()--> [unicode] ==>encode()--> utf-8文本 ^ ^ ^ ^ ^ | | | | +- 最终的渴求 | | | +- 是为编码过程;可以从unicode 输出为任意编码 | | +- Python 内置支持的unicode 格式数据 | +- 是为解码过程,将已知编码的文本编译成宇宙通用的unicode数据 +- 原始文本信息,是什么编码你得知道!
- 也就是说文件没有编码之说,大家其实都是二进制格式保存在硬盘中的,仅仅是在写入读取时需要使用对应的编码进行处理,以便操作系统配合相关软件/字体绘制到屏幕中给人看
- 所以,关键问题是得知道原先这些字串数据是使用什么编码来编译的!
- 但是,在Unicode 之前,都是使用类似对照表的形式来组织编码的,无法从串数据流本身中统一解出不同的文字来,
- 只有猜!
猜编码函式一 def _smartcode(stream): try: ustring = unicode(stream, 'gbk') except UnicodeDecodeError: try: ustring = unicode(stream, 'big5') except UnicodeDecodeError: try: ustring = unicode(stream, 'shift_jis') except UnicodeDecodeError: try: ustring = unicode(stream, 'ascii') except: return u"bad unicode encode!"
- 嗯嗯嗯,收集的音乐可是不仅仅中文的,印度,伊朗等等音乐都可能有收集,逐一去尝试,这个判定树就太可怕了!
- 升级!使用Python 的数据对象进行集成!
1 # 猜编码函式二
2 def _smartcode(stream):
3 tryuni = ("gbk"
4 ,"gb2312"
5 ,"gb18030"
6 ,"big5"
7 ,"shift_jis"
8 ,"iso2022_kr"
9 ,"iso2022_jp"
10 ,"ascii")
11 try:
12 for type in tryuni:
13 try:
14 ustring = unicode("%s}"%type+stream, type)
15 #try decode by list
16 except:
17 continue
18 #break!continue try decode guess
19 except:
20 return u"bad unicode encode!"
- 但是....
详细:: PCS6 Python与中文 进一步全面的阐述了在Python 中面对中文数据时的思路和技巧... PCS112 异常 讲述了Python中异常的使用,即try ... except ...的使用等
chardet
这么一项项猜,还是显的很傻的哪,万一有些字的高位在不同编码中是相同的,那真的是只能撞大运了!
尤其是对可怜的难兄难弟: gbk和big5.
- 比如:
>>> print '变巨'.decode('big5') 曹操 >>> print '变巨'.decode('gbk') 变巨
问吧...行者们给出个地址:" http://chardet.feedparser.org/ "
- -- Character encoding auto-detection 自动字符探测器!
- 呃真的有哪! 而且是 Mozilla 使用的! 立用不疑!
嗯嗯嗯?!怎么安装外部模块的呢?软件包下载,解开压缩,嗯嗯嗯?没有INSTALL 说明文件, 但是有个setup.py 尝试执行一下?
~$ ls -l 总用量 33 drwxr-xr-x 3 zoomq zoomq 72 2008-04-29 11:25 build drwx------ 2 zoomq zoomq 1264 2006-01-11 01:34 chardet -rwx------ 1 zoomq zoomq 26432 2006-01-11 01:34 COPYING drwxrwxrwx 4 zoomq zoomq 296 2006-01-11 01:34 docs -rwx------ 1 zoomq zoomq 1981 2006-01-11 01:34 setup.py ~$ python setup.py usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] or: setup.py --help [cmd1 cmd2 ...] or: setup.py --help-commands or: setup.py cmd --help error: no commands supplied ~$ sudo python setup.py install running install running build running build_py running install_lib running install_egg_info Removing /usr/lib/python2.5/site-packages/chardet-1.0.egg-info Writing /usr/lib/python2.5/site-packages/chardet-1.0.egg-info
so easy! 好象使用了类似小白已经完成的交互式提醒哪! 看来所有Python 的软件都可以通过python setup.py install 进行安装哪!
详细:: PCS202 chardet 进一步说明了此外部模块的信息, 并分享了使用体验;
1 import chardet
2 def _smartcode(stream):
3 """smart recove stream into UTF-8
4 """
5 ustring = stream
6 codedetect = chardet.detect(ustring)["encoding"]
7 print codedetect
8 try:
9 print ustring
10 ustring = unicode(ustring, codedetect)
11 print ustring
12 return "%s %s"%("",ustring.encode('utf8'))
13 except:
14 return u"bad unicode encode try!"
经过测试在各种情况下都可以正确识别!
但是不论怎么尝试已经保存下来的 .cdc 文本依然是 ASCII 码!
另外思路
也许真的就是 ASCII 码呢?
幸福的自由
- 冷静一下 -- "既然,文件没有编码都是二进制的,那么光盘文件是如何被系统认识的?!"
- 在列表中吼了一下,行者们有点无奈的说:"TiosnG!"
~ There is one site named Google!
好吧,小白老实的搜索了一番,发现了iso9660 -- 嗯嗯嗯,所有光盘基本都是此文件格式的,同M$使用的 FAT32/ntfs,GNU/Liunx 使用的 ext2/3,Unix使用的UFS...一样,只是种文件系统
- 则必然是通过某种软件进行转换从而可以访问的
咳 -- Ubuntu 中当然是标准的调用 朴实强大的mount命令了
~$ cat /etc/mtab ... /dev/sda3 /dos vfat rw,utf8,umask=007,gid=46 0 0 ... /dev/sda1 /windows ntfs rw,nls=utf8,umask=007,gid=46 0 0 /dev/scd0 /media/cdrom0 iso9660 ro,noexec,nosuid,nodev,user=zoomq 0 0 ...
观察默认的挂接光盘的行为和挂接 Dos 和 Windows 分区的情况,感觉是默认的挂接行为没有使用编码处理- 那么通过改变挂接行为,应该可以改善读取不到正确文本的情况?!
#挂接成GBK ~$ sudo mount -o ro,norock,iocharset=cp936 /dev/scd0 /media/cdrom0 #挂接成UTF8 ~$ sudo mount -o ro,norock,iocharset=utf8 /dev/scd0 /media/cdrom0
- 咔咔咔!果然!果然!
- 相对M$ 系统,安装成什么语言的系统,就永远使用什么编码强行挂接光盘的,好象似乎八成应该不是可以轻易的按照你的意愿改门厅的...
- 以前小白对于自由软件的认识仅仅是免费,难用--这下忽然间有所顿悟,不觉写下感慨:
自由软件好,我用我自在!
- 自由之所以,自由是基于对自个儿的了解,真正理解了自个儿想要什么之后,自由软件支持你的一切尝试!哈哈哈!
小白可以感受到这些可以算是小灰了,可以稳定的向成熟的小黑 -- 一名黑客挺进了!
警告:: Hacker~黑客 绝然不是中国媒体中宣传的那些攻击他人电脑的家伙, 黑客是些创造技术奇迹的单纯的人们: http://wiki.woodpecker.org.cn/moin/HackerHowto(精巧地址:http://bit.ly/31rUuY) 被翻译所误指的是 骇客~Cracker http://en.wikipedia.org/wiki/Cracker(精巧地址:http://bit.ly/3Xx0A) 破坏者 未经授权而企图进入电脑系统者。这种入侵者通常是恶意进入他人的系统, 而且有许多技巧可以破坏他人的系统。 这个名词是骇客(Cracker)在1985年为对抗新闻媒体滥用hacker而提出的。 1981-1982年前曾有人推动使用毛虫代表与cracker一样的意义,但并未成功。
改善数据结构
查询是可以了,但是,使用默认的列表打印格式来存储和汇报实在不乍的, 想修改就修改
详细:: PCS107 字串格式化 进一步介绍了这里用来快速重构 光盘信息文本格式的 Python 内置的字符模板支持特性;
存储下来的 .cdc 片段
... -f /media/cdrom0/RyokoHirosue/Ryoko Hirosue-files.files title.gif ====================================================================== /media/cdrom0/RyokoHirosue/成长物语 -d /media/cdrom0/RyokoHirosue/成长物语 音乐极限--成长物语.files -f /media/cdrom0/RyokoHirosue/成长物语 RH991101.mp3 -f /media/cdrom0/RyokoHirosue/成长物语 RH991102.mp3
d代表目录;f代表文件,他们分别是directory(目录)和file(文件)的缩写
小结
图 CDay-1-6 CDay-1问题解决思路图谱
这日,小白仅仅解决了一个问题 -- 中文搜索问题;解决尝试路途及相互关系如上图所示 但是,实际上获得了两大方面的进步:
- 文本编码方面的知识
- 问题解决的方法论境界提高了一个层次,开始使用系统级别的解决方案
相对Python 方面,仅仅追加了一对内置函式,和一个外部模块包使用的体验
关键词:
- 编码
- unicode
- chardet
- mount
注意
如果你使用M$ 系统,运气好的话,是不会见到笔者列出的现象的,但是不保证以后遇不到自动处理下搞不定的光盘内容;希望那时候小白真的有个自由环境可以尝试其它方案
警告:: 事实上有在Windows 下面的完全Unix环境 Cygwin http://www.cygwin.com 是一个运行于Windows下的免费的UNIX的子系统,使用一个Dll(动态链接库)来实现的虚拟机, 可以直接在 Windows 环境中使用各种Unix 实用工具;
练习
1. 自动判定你自个儿或是朋友的Blog 是什么编码的?
2. 如果是非utf-8 的,编写小程序自动将指定文章转换成utf-8 编码保存?