python中,一切皆对象。做为面向对象开发中非常重要的一个环节,函数有着无可替代的作用。
函数可以作为对象赋值给一个变量,可以作为元素添加到集合对象中,可以作为参数值传递给其它函数,还可以当做函数的返回值被引用。
在现代软件开发之中,有一个非常重要的原则,那就是开放封闭原则。
所谓开放封闭原则就是软件实体应该对扩展开放,而对修改封闭。
开放封闭原则是所有面向对象原则的核心。
软件设计本身所追求的目标就是封装变化,降低耦合,而开放封闭原则正是对这一目标的最直接体现。
开放封闭原则主要体现在两个方面:
对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
对修改封闭,意味着类一旦设计完成,就可以独立其工作,而不要对类尽任何修改。
为什么要用到开放封闭原则呢?
软件需求总是变化的,世界上没有一个软件的是不变的,因此对软件设计人员来说,必须在不需要对原有软件代码进行修改的情况下,实现灵活的系统扩展。
如何做到对扩展开放,对修改封闭呢?
在python中,有一个很好的设计,那就是装饰器。装饰器的作用就是为已经存在的函数对象添加额外的功能
装饰器本质上是一个Python函数,可以是任意可调用对象,被装饰对象也可以是任意可调用对象。
装饰器的功能是:
在不修改被装饰器对象源代码以及被装饰对象的调用方式的前提下,为被装饰对象添加新功能
例如:
import time
def index():
time.sleep(3)
print("Welcome to index page")
index()
结果会打印"Welcome to index page"这句话。那么,假如现在我想为这个函数添加一个统计这段程序运行时间的功能,在符合开放封闭的前提下怎么实现呢?
用装饰器就可以实现了。
import time
def timmer(func):
def wrapper():
start_time=time.time()
func()
stop_time=time.time()
print("The page run time is %s"%(stop_time-start_time))
return wrapper
@timmer
def index():
time.sleep(3)
print("Welcome to index page")
index()
运行结果如下:
Welcome to index page
The page run time is 3.000171422958374
在这段代码里,在index函数的上面一行的那个@timmer就是装饰器的专有语法,其调用方式等同于:index=timmer(index)。
程序运行步骤:
1.程序执行index函数,此时相当于执行index=timmer(index),把index函数作为一个参数传递给timmer这个函数。
2.调用timmer函数时,就相当于是在调用timmer函数的内部函数wrapper。
3.index作为timmer外层函数的参数,在wrapper这个内部函数的里面也在调用。
4.在wrapper函数调用完成后,执行的结果又返回给wrapper函数,此时相当于把index函数,以及打印程序运行时间的功能执行的结果返回给timmer这个函数。
5.如前所述,timmer函数的执行结果也就等同于返回给index函数,这样就完成了装饰器的调用过程。
在这段代码里,原有的程序就是index函数部分代码未做任何修改,index函数的调用方式也未做任何改变,统计程序的运行时间的功能也已经添加完成,这里就使用了装饰器的功能。