1.装饰器
1 #!/usr/bin/env python 2 #encoding=utf-8 3 4 import time 5 6 def foo(): 7 print 'in foo()' 8 9 # 定义一个计时器,传入一个,并返回另一个附加了计时功能的方法 10 def timeit(func): 11 # 定义一个内嵌的包装函数,给传入的函数加上计时功能的包装 12 def wrapper(): 13 start = time.clock() 14 func() 15 end =time.clock() 16 print 'used:', end - start 17 18 # 将包装后的函数返回 19 return wrapper 20
21 print '1' 22 foo = timeit(foo)
23 print 2 24 foo() 25
打印结果:
1
2
used: 0.0
一个简易的计时器就做好了!我们只需要在定义foo以后调用foo之前,加上foo = timeit(foo),就可以达到计时的目的,这也就是装饰器的概念>,看起来像是foo被timeit装饰了。在在这个例子中,函数进入和退出时需要计时,这被称为一个横切面(Aspect),这种编程方式被称为面向切面>的编程(Aspect-Oriented Programming)
语法糖:
1 import time 2 3 def timeit(func): 4 def wrapper(): 5 start = time.clock() 6 func() 7 end =time.clock() 8 print 'used:', end - start 9 return wrapper 10 11 @timeit 12 def foo(): 13 print 'in foo()' 14 15 foo() 16 重点关注第11行的@timeit,在定义上加上这一行与另外写foo = timeit(foo)完全等价,千万不要以为@有另外的魔力。除了字符输入少了一些,还有一个额外的好处:这样看上去更有装饰器的感觉
内置的装饰器
内置的装饰器有三个,分别是staticmethod、classmethod和property,作用分别是把类中定义的实例方法变成静态方法、类方法和类属性。由于模块里可以定义函数,所以静态方法和类方法的用处并不是太多,除非你想要完全的面向对象编程。而属性也不是不可或缺的,Java没有属性也一样活得很滋润。从我个人的Python经验来看,我没有使用过property,使用staticmethod和classmethod的频率也非常低。
1 class Rabbit(object): 2 3 def __init__(self, name): 4 self._name = name 5 6 @staticmethod 7 def newRabbit(name): 8 return Rabbit(name) 9 10 @classmethod 11 def newRabbit2(cls): 12 return Rabbit('') 13 14 @property 15 def name(self): 16 return self._name
这里定义的属性是一个这里定义的属性是一个只读属性,如果需要可写,则需要再定义一个setter:
1 @name.setter 2 def name(self, name): 3 self._name = name