Posts Tagged ‘ Python

一些python

最近在试着读OpenStack Nova的源代码。不看别人的代码不知道自己是有多无知啊…

1.协程(Coroutine)

按我现在的理解,协程是比线程还要轻的一种程序并发执行方式。Python用“yield”这个关键字提供了对协程的支持。

看个例子就懂了:

def foo():
    for i in range(10):
        yield i
        print 'foo: here ' + str(i)

bar = foo()

print bar.next()
print 'main: here'
print bar.next()
print bar.next()

例子的输出是:

0
main: here
foo: here 0
1
foo: here 1
2

在协程里,yield起到的是类似return的作用,但是远没有return那么重:没有进程/线程调度,也就不必保存现场,函数只是暂停,过会儿还会从yield处继续执行。而如果yield后面不跟变量,甚至可以把yield看作一个标记,表示这个位置上,函数可以暂停。

上述例子中,代码的执行流程是这个样子的:第一个bar.next()输出i = 0,之后foo()函数暂停,main输出“main: here”,然后每次执行bar.next()输出“foo: here i”,然后返回打印出i。

协程的主要应用场景是服务器端的编程。因为它比线程更轻,所以可以支持更大的并发数。

举个例子,假如在服务器端生成了10000个协程,然后开始运行“调度”函数。当新的连接进入时,“调度”函数给新连接分配一个协程,而当这个协程进行IO时,会暂停让出CPU,“调度”函数再选择其它协程执行。跟进程调度很像,但是协程并没有被“阻塞”,事实上,上述的10000个协程可以是运行在一个线程中的。

OpenStack里面使用了一个叫eventlet的基于协程的网络编程库

主要参考12

2.@修饰符(decorator)

官方文档说修饰符只是一种语法糖(syntactic sugar),简单来说,就是下面两段代码是完全等价的。

def foo(arg):
    some code
foo = bar(foo)
@bar
def f(arg):
    some code

主要参考1

3. @classmethod和@staticmethod

在一个类里面,可以存在三种方法:实例方法、类方法、静态方法,定义方法如下:

class Foo(object):
    def instanceFoo(self,x):
        some code

    @classmethod
    def classFoo(cls,x):
        some code

    @staticmethod
    def staticFoo(x):
        some code

最显然的区别,就是他们接受的参数是不同的。实例方法必须接受一个实例(self),类方法必须接受一个类(cls),静态函数没有要求。

静态方法在python里用途不大,因为class.staticmethod()和module.normalfunction()不管从外观还是从作用都区别不大。而类方法可以用来进行类的实例化:

>>> class DictSubclass(dict):
...     def __repr__(self):
...             return "DictSubclass"
...
>>> x = dict.fromkeys('ab')
>>> print x
{'a': None, 'b': None}
>>> y = x.fromkeys('qwe')
>>> print x,y
{'a': None, 'b': None} {'q': None, 'e': None, 'w': None}
>>>

主要参考 12

4.*arg,**arg

这个不是指针,当参数为*arg时,表示接受一个元组;当参数为**arg时,表示接受一个字典

主要参考1

5.继承/多重继承中的参数传递

在继承/多重继承中,参数是逐级向上传递的,最后传递给object(python里一切对象的基类)时,参数应该已经处理完毕。

看个例子:

class Service(object):
    def __init__(self, host, binary, topic, manager, report_interval=None,
             periodic_interval=None, *args, **kwargs):
        print 'Initializing Service'
        super(Service, self).__init__(*args, **kwargs)

        print 'Service: ' + binary, args, kwargs

class Color(object):
    def __init__(self, color='red', **kwargs):
        print 'Initializing Color'
        self.color = color
        super(Color, self).__init__(**kwargs)

        print 'Color: ', kwargs

class ColoredService(Service, Color):
    def __init__(self, *args, **kwds):
        print 'Initializing Colored Service'
        super(ColoredService, self).__init__(*args, **kwds)

c = ColoredService('host', 'bin', 'top', 'mgr', 'ivl', color='blue')

输出是:

Initializing Colored Service
Initializing Service
Initializing Color
Color:  {}
Service: bin () {'color': 'blue'}

在这个例子里,ColoredService继承了Service和Color,首先初始化ColoredService,然后是Service,此时类Service“吃掉”了传来的大部分参数,只剩下{‘color’: ‘blue’}。然后初始化Color,最后是object。假如传递到object时参数还没有被吃完,python就会报“TypeError: object.__init__() takes no parameters”的错误。

而在多重继承中继承顺序的确定是用了一种叫做C3 Method Resolution Order(MRO)的算法

主要参考12

又一个script的总结

被分到给video.edu.cn做助管,其实就是成天扛着摄像机到处录讲座

讲座信息的来源是北邮内网的信息发布栏,那个略带强迫症的学长教导我们,要养成看通知的习惯…

然后就有了这个script(代码不贴了,很丑,也没有普适性,说了是“总结”的嘛)

主要功能就是从发布栏上按关键字提取讲座信息,然后邮件发给自己和其它助管…

1.关键字

观察了下学术办的讲座通知格式,取了“讲座通知”和“报告通知”两个词,而不单单是“讲座”,否则会出现类似“迪斯尼高级画家范新林先生讲座成功结束!”这种杂质

2.encode()和decode()

处理中文始终是件很烦的事情,不过终于有点感觉了

在py文件开头用coding定义了编码是utf8,然后那个网站的编码是gb18030,所以用urlopen()拿回来的数据编码格式就是gb18030的,如果要在Mac OS X下显示,就要以gb18030的格式decode()成utf8的,而在py文件里输入的文字,要想跟网站数据做比较,就要encode()成gb18030了

简单来说,就一句话,encode()和decode()都是相对于utf8这个默认编码而言的

3.正则匹配中文

范围是\x80-\xff,貌似也包括标点符号和一些奇奇怪怪的符号

4.html2text和sendemail

从网上找了两段现成的代码,不要重做轮子嘛:) 当然都改了一下来适应我的需求

5.定时任务

Mac OS X自带cron,搜了一下用法,也误入歧途过,写这个脚本花时间最多的居然是在这个上面- -b…

不晓得为神马,crontab这个命令是不好使的(系统10.7.2)

然后ps -A看了下cron确实在后台运行着,继续搜,发现应该编辑/private/etc/crontab或者/etc/crontab(这俩是一个文件),文件格式是:

#min     hour     day     month     day/week    user     command

 0       11       *       *          1-5        can     /Users/can/Desktop/web/run.sh

上面配置的意思是,每周1到周5的11点0分,以can的名义运行run.sh这个脚本

cron还有一些其它的语法,相当灵活

又一个发短信的script

需求的产生是这样子滴…

印象里去年还是前年过年的时候看到一条校内状态,大意如下:

“XX啊,过年好啊…”短信虽然字数不多,但看得出来是专门为我写的,很感动

于是我萌生一个想法…效果就是这个样子滴啦~

给邹邹的短信

而生成这条短信的原始内容是:

[NAME]啊…小规模短信群发测试…把你收到的内容转发给我…thankU4cooperation[NAME][NAME][NAME][NAME][NAME]

算是一种投机取巧吧…把[NAME]换成了对人的称呼…每一条短信”看起来”像专门为别人写的一样…

上次是PyS60,这次是sl4a…但语言是没变的,还是Python…

sl4a的API感觉还比较简陋,而且文档和样例也都很简陋…

还有就是不持支读写手机上的文件,使得我不得不转变思路,把脚本和数据合并成一个文件再丢到手机上运行…

包括下面4个文件,在这里下载

文件

raw.py : 用于生成output.py的原始文件

sms.txt : 要发送的短信内容

nameMap.txt : 名字映射文件,格式是[通讯录名称]:[昵称].这其实也是一个发送目标的清单…

merge.py : 运行后生成output.py,也就是最后丢到手机上的文件

在手机上跑起来是这个样子:

短信发送后

678行—the very best of SauceForge

长舒一口气…终于赶在晚上11:45…赶在12点之前…把程序提交了

据说这次的代码量达到了空前的678行(我没数过),分成了5个文件…

终于体现了一点面向对象的思想,但还是面向过程的方式居多

中兴捧月复赛程序框架

这次最大的收获是自己从无到有实现了一个还算健壮的协议…发现协议这个东西还可以琢磨地有滋有味:)

很多try…except…不测试是永远不会发现”居然还会有这种问题”的

而且线程之间的同步到目前为止还是很迷惑…只是会建立起来,跑起来,看起来能用的感觉…

还有,Python绝对八面玲珑…之前说过了…推荐所有折腾人士使用

伪球迷的世界杯,只有一场完整的比赛

今晚的荷兰对西班牙…放松一下~