Posted by conan | Posted in 总结 | Posted on 27-04-2010
做了手机天气预报和rss generator,有必要把处理字符串信息过程中遇到的问题总结一下了。
在做这两个东西的时候对python有了一些初步的理解,python用起来真的很舒服。数据结构,函数方法等都能够让你写出简短易读的代码。做天气预报的时候出现的问题比较简单,因为信息处理都是自己做的,只有发送的时候使用飞信库,所有抓取的信息甚至都不用解码,在程序里处理后直接发送出去就行,需要注意的就只有程序里写的字符要使用unicode,发送前进行编码就行了。做RSS生成的时候使用了PyRSS2Gen库,最后写入文件是使用此类库的函数进行的,在认知上出了点偏差,发生了不少的错误,饱受折磨好几天。
简而言之,把握住以下几点,在python中进行信息处理的时候应该不会再遇到这么多的信息编码问题。
1.在取得信息的时候(从文件,网络中)尽快进行解码,在程序中使用被解码的信息进行处理,在信息被写出去的时候(写到文件,网络等)再进行编码。
2.关于编码和解码,概念一度被我理解的比较混乱。首先是这个:
>>> “a”.decode(‘ascii’)
u’a’
>>> u’a’.encode(‘ascii’)
‘a’
这个到底怎么理解呢?我一直认为unicode和ascii是一个类别的,类似raw data的那一种,现在发现不对。因为unicode只是规定了字符集,但是没有规定存储方式,所以只有unicode是类似于raw数据的,它离开存储方式无法生存,而ascii则字符集和存储方式都有,所以说unicode可以作为一种内部数据处理方式,但是不能用来存储。所以,u’a'是unicode字符串,它被ascii进行编码之后出现ascii编码下的a,而’a'也可以被解码为unicode的字符串u’a'。于是在处理数据的时候,其实ascii是应该和utf-8,gb2312这种编码处于一个类别里。由于历史原因,ascii不管在什么地方都会获得良好的支持,所以ascii的信息不经过任何编码解码处理都不会有什么问题,而网络上编码千变万化,比如在中文互联网中gb2312和utf-8就经常相互打架。总结一下,编码和解码的过程应该这样处理,如果是ascii编码,完全不用理会编码解码的问题,而如果是utf-8或者gb2312这种,在取到的时候应当对其进行解码,这样数据就变成了unicode字符串,它适合在程序内部进行处理,在需要对其进行输出的时候,把它进行编码,需要utf-8的就编码为utf-8,需要gb2312的就编码为gb2312。
在rss生成的时候遇到的UnicodeDecodeError的问题,最后确认是因为对某些数据提前进行了encode操作,而写操作的时候依然需要进行encode操作。在python中,已编码的字符串也有encode方法,其操作是按照默认的ascii编码进行解码操作,然后再进行encode[2]。已编码为utf-8的字符是无法被ascii编码进行解码操作的,于是这个过程中就是把编码过的数据当作未编码的数据,试图对其进行解码导致了错误。参考如下,取自第二篇:
Why do Python byte strings have an encode() method?
The sharp-eyed amongst you will have noticed that byte strings have an encode() method as well as a decode() method. What does this do? Quite simply, it does a decode-then-encode. The byte string is decoded to Unicode using the default (ascii) encoding, and is then encoded to the target encoding specified in the call to encode() using the appropriate encoding. As you’d expect, fun and games ensue if the original byte string isn’t actually encoded in ASCII at all.
最终总结:对于python2.5而言,字符类型就两种,str和unicode[3],下图中左边是str,右边是unicode。
ascii—————–decode(‘ascii’)——-┐
utf-8—————–decode(‘utf-8′)——–┼—unicode
gb2312————decode(‘gb2312′)—┘
反之为encode操作。
参考:
1.python核心编程第二版
2.Python, Unicode and UnicodeDecodeError,地址在这里(英文,讲的很好)
3.Re: u’吴’和’吴’有什么区别? ,地址在这里
Posted by conan | Posted in 总结 | Posted on 25-09-2009
最近用python重写了天气预报,对python的变量名有了一些认识。
python的变量名和以前接触过的c/c++等完全不一样。c/c++的变量名的思想应该是这样,分配之后变量名就永远的关联到了编译器分配到的内存,任何对此变量名进行的操作都最终落实在对这段内存的操作上。
python中的变量名更像lisp的感觉,内存和变量名的关系并不是永远“绑定”的,这个变量名更像是一个指针,它指向了那个“变量”。
拿最简单的a=1来做例子。在c/c++中,=的意义是赋值,它对应的操作是把1赋值到a所指向的内存中。1这个表示在c/c++中是一个int型整数,存到a对应内存的是int型的整数1。为什么不同类型的赋值会出错?因为那个变量所指向的是一段可存储被赋值类型的内存空间,无法保证这个不同的类型在那段内存不出现问题。(由此引出的类型转换暂不考虑)如果再用b=a,则是将a的内容复制到b中去。在python中,=的意义虽然也是赋值,但是它做的完全不是这样的操作。根据python的声明,一切都是对象(变量名是不是还没有体会到),那么这个1也是对象,a=1就是将a指向1这个对象,而再用b=a则是将b指向a所指向的内容。那既然a和b都指向同一个地方,为什么修改了a之后b不变呢?举例,执行a=2,再看b的话你会发现还是1。其实这个还是惯性思维的原因。a=2实际上执行的操作是将a指向2这个对象,而不是将a所指向的内存改为2,所以a指向了2,而b还是指向1。可以体现这一点的比较容易的方法是用字符串。如果你用下标改了字符串的内容,两个“变量”都会变。
所以在python中,变量名不如叫名字(name)更为贴切,而在这种机制下,名字空间就显得尤为重要。
注:此文没有经过c/c++编译器及python解释器的证明,如有错误请指出,多谢
Posted by conan | Posted in 总结 | Posted on 23-06-2009
前言:其实是寒假在家看的,一直总结到现在才发上来。这些就是我看到的sed的精华部分了。
替换:
命令格式:地址范围s/匹配模式/替换字符/选项
/为分界符,可以用别的字符。s后的第一个字符会被识别为分隔符,要求不能是空格或制表符,且能将三段内容分开。
地址范围:数字或模式,如 1 1,4 /A/ /A/,/E/
匹配模式:可用基本元字符,另外可以用( )
替换字符:可写正常文字,也可有特殊字符:
&:代表匹配模式中正则表达式配的字符串。例:s/ab/&cd/
\n:与模式中第n(数字)个\( \)制定的字符串匹配。有点类似子式
\:转义替换特殊字符,如&,\,替换命令的分界符
选项:n:指定第n次出现时替换。(1~512)
g:所有目标均替换。
p:输出模式空间的内容。
w:写模式空间的内容。
删除: 地址范围d 整行删除
附加: 定位地址a\
文本 在定位到的行下面加一行,内容为命令中的文本
插入: 定位地址i\
文本 在定位到的行上面加一行,内容为命令中的文本
变换: 定位地址c\
文本 把定位到的行整行替换掉
*插入和附加不可与地址范围同用,交换可以
sed控制步骤:
1.预处理步骤。将下一行读入模式空间。
2.处理步骤。在模式空间中直接处理所有命令。
3.后处理步骤。输出模式空间并返回第一步骤。
*.删除命令出现后立刻停止处理步骤,并且跳过后处理步骤。
**.插入,附加,变换均为后处理步骤操作。变换先删除模式空间,然后返回后处理模式。
列表: l 前面也可加地址范围,一般用法是用-n参数禁止缺省输出再用 它来处理想要输出的部分。另外它会将不可打印字符输出。
输出: p 同列表命令相似,区别大概是不输出不可打印字符。
= 输出行号,不过在对应行的上一行(?)
转换: 行地址y/abc/ABC/ 将每一个a变为A,b变为B…对应位替换。
下一命令: 行地址n 向模式空间读入下一行,直接转入后处理步骤。
读入文件: 行地址r 文件
写文件: 行地址w 文件
多行下一行: N 将输入文件的下一行附加到模式空间的当前行之后,两端内容
间用换行符\n分开,可配合s将换行替换为空格。
多行删除: D 删除内容只第一个换行符(然后直接转到后处理步骤)
多行打印: P 输出模式空间至第一个换行符
驻留空间:除模式空间外的另一块临时空间。
驻留: 行地址h 将匹配的行覆盖驻留空间内的内容
H 附加到驻留空间,并加入换行符
获取: 行地址g 用驻留空间内容覆盖模式空间的内容
G 将驻留空间的内容附加到模式空间后面,并用换行符分隔
交换: 行地址x 交换驻留空间与模式空间的内容
附:ibm的sed教程(比我的详细很多)
http://www.ibm.com/developerworks/cn/linux/shell/sed/sed-2/index.html
Posted by conan | Posted in 总结 | Posted on 22-06-2009
又是思维巨变的半年,应该总结一下。出于机缘巧合(看到了4G space和mindhacks)得窥天机(夸张了),开始了思维的进化。由于看到了那样的一种境界,自己是极其羡慕,便不由自主地想去触碰,去达到那种境界。那种对于计算机结构的融会贯通和对人类行为的科学分析就就这样吸引了我。
对知识的渴求造就了我第二段的学习热情高涨。现在我几乎每天都会去学习,但是平心而论,却会比第一段学习热情高涨(出生~小学毕业)的效率低不少。潜力还有很多,但是不知道怎么去挖掘,这让我对自己非常的不满。虽然我知道这样会影响自信,但是却没有办法停下来。也许因为《编程之道》,也许因为《Unix编程艺术》,现在看专业有了一个完全不同的眼界。这学期开始的时候还在看c++ primer,但是一段时间之后放弃了。高级语言各得其道,不可能一种语言通吃天下。看到这个之后,就此跳出了语言的束缚,开始往更深的地方望去。关于语言现在选择了两个极端,c和Python,然后以此开始了在计算机世界的求道之旅。自己总结了一下,现在有三条出路可以走,这条录是最想走的,而且是最困难的。现在的感叹就是时间太少了,效率又不够高,自己买的书都来不及看。什么时候才能有梦寐以求的如宝剑一般犀利的思维呢。。。
这半年,我意识到了自信的力量,意识到了人皆可以有自己的自信,然后以此迸发出奇妙的魅力。那么我的“隐”法处世也要做一些修正了。这半年,感情依然没有进展,依然不会与女生相处,依然会把相处的还不错的女生丢了。若是以前,这条根本不会写进来。但是已经理智到这种程度的我,第一次有了找女友的冲动。最好的朋友之二订婚了,似乎前不久还在和他们一块打闹玩耍。他们订婚的刺激程度比听说100个同龄人订婚都强烈。不过话说回来,这个不是计划可以控制的。。。先消化一下这种冲动吧。
Posted by conan | Posted in 思考, 总结 | Posted on 27-05-2009
虽说不是第一次安装gentoo,不过上次是livecd安装,这次直接在ubuntu里安装的,比上次的通用性和理解都好很多。理解之后就不会再执着于到底是光盘安装,或是硬盘安装,或是用什么镜像安装的形式。
具体参考gentoo手册x86版
http://www.gentoo-cn.org/doc/zh_cn/handbook/handbook-x86.xml?style=printable&full=1
下为抽象出来的思路:
- 关于如何安装Gentoo Linux
本章介绍了本手册所讲解的安装方式。
(一些常识)
- 选择合适的安装方式
你可以用许多方法安装Gentoo。本章讲解怎样用最小安装光盘安装Gentoo,尽管使用安装程序LiveCD也是可以的。
(还是一些常识(有些不大懂 – -)。获取安装镜像,验证镜像有效性,用最小安装光盘来组成最小系统,然后从这个系统上进行安装)
- 配置网络
要下载最新的源代码,你要先设置好网络。
(使最小系统能够连接网络,好下载安装包。)
- 准备磁盘
为了能够安装Gentoo,你必须创建所需的分区。本章讲解如何给磁盘分区以备后用。
(准备好要安装gentoo的磁盘分区)
- 安装Gentoo安装文件
我们使用一个stage3文件来安装Gentoo。在这一章里我们将教你如何解压缩stage3文件和配置Portage。
(安装包有两个,stage3和portage,stage3可以理解为最小的gentoo系统,里面是一个普通linux系统的根目录下的所有东西;portage为gentoo的软件包管理工具,记录了所有的软件包依赖关系,并含有emerge工具用来安装各种软件,地位相当于debian系中的apt-get)
- 安装Gentoo基本系统
安装并配置完stage3以后,你就会有一个可用的Gentoo基本系统了。这一章将教你如何达到这一状态。
(组织分区,用chroot命令将当前shell的根目录更改为gentoo的分区,当前session下所有操作均调用gentoo分区的命令,相当于已经进入这个“半成品”的系统)
- 配置内核
Linux内核是每个发行版的核心。本章节将解释如何配置您自己的内核。
(手工配置未遂,启动不能,于是genkernel搞定,没办法,经验太少,人也笨。。。 – -)
- 配置系统
你需要编辑一些重要的配置文件。在这一章中将对这些重要的配置文件作概述,并且介绍如何配置它们。
(给系统做基础配置,包括硬盘挂载方式(重要),系统的网络设定,root密码)
- 安装必要的系统工具
在这一章中我们将帮助你选择并安装一些重要的工具。
(一些系统服务)
- 配置引导程序
x86架构存在几种引导程序。它们中的每一种都有自己的配置方法。我们会一步步来告诉你怎样根据你的需求配置一个引导程序。
(简单且片面的说,就是grub的安装和写菜单咯~全面的自己去理解吧:P)
- 结束Gentoo的安装
您几乎已经完成了。接下来我们只需要为您的系统创建一个(或更多)用户就可以了。
- 下一步该做什么?
现在你已经拥有了你自己的Gentoo操作系统了,但是下一步该做什么呢?
(没啥了,自己看吧~)
总结:
第一步,建立起一个基本系统,配置好它,准备安装。
第二步,准备好要安装的分区。
第三步,下载stage和portage包,一个是基本系统,一个是软件包安装工具。
第四步,配置分区和portage包,并且切换根目录过去,进入“新系统”。
第五步,配置并编译内核。
第六步,配置新系统,善后。
ps:简单的说,这个安装过程虽说比其他系统那么方便的安装要麻烦很多,但是很有助于理解系统。经过这个过程你可以大概了解到一个正常的linux系统安装都会做些什么。
Posted by conan | Posted in 总结 | Posted on 07-05-2009
grep&sed:基本元字符
句点 .
星号 *
字符组 [ ]
位置 ^$
范围 \{n,m\}
反斜杠 \
词 \< \>
egrep&awk:扩展元字符(除基本外还可以用这些,用法冲突的这边优先)
加号 +
问号 ?
竖线 |
括号 ( )
范围 {n,m}
fgrep:无任何元字符,所有字符都识别为文本