装饰器、生成器
装饰器主要用于程序功能的一些扩展。
由于在python中,函数名(不带括号)也是一种变量名,可以像赋值一样给另外一个变量。这就导致了装饰器这种玩法。
其实函数名就是保存着函数的地址,因此,可以把这个地址赋值给另外一个变量,与c语言中的指针基本一样,同时与python列表的引用也是相像的。
不附加新参数的装饰器比较简单
def decorator(func): def inner(): .扩展的功能 . func() 扩展的功能
return inner def new_old(): .....
new_old=decorator(new_old) #①将函数new_old传递给形参func,func=new_old
#②执行函数decorator(func),由于函数decorator()里面只定义了inner,且并未调用,因此,直接执行return inner。new_old=inner,将函数inner的内存地址赋值给了new_old
new_old() # ③执行new_old(),此时相当于执行inner(),由于inner中未定义参数func,程序会自动去上一级找该参数。而在第一步我们已经将最初的new_old赋给了func。所以本步骤执行new_old(),就相当于执行inner(),并且inner中func已确定。
python中实现装饰器可以采用这种格式
@deccorator
def new_old():
...
这样就代替了 new_old=decorator(new_old) 这段代码。
如果要装饰多个函数,且不同函数自身所需参数不同:
def decorator(func): def inner(*args): . . func(*args) @decorator def new_old(a,b,c): ... @decorator def old(a): ... @decorator def new(): ...
这样执行每一个函数,都会将装饰器执行一遍。
对于附加新参数的装饰器会稍微复杂一些:
def decorator(s): def outter(func): def inner(*args): if s='ss': . .... func() elif s='aa': ..... func(*args)
return inner
return outter @decorator('ss') #此处相当于new_old=decorator('ss')(new_old),注意 decorator('aa') 其实就是outter。函数outter(new_old) return的是inner,因此new_old=inner
def new_old(a,b,c):
...
@decorator('aa')
def old(a,b,c):
...
如果想添加两个参数,@decorator('ss',‘yy’)
由于装饰器是在程序运行前就将参数内化了的(闭包),@decorator(s,y),这种变量名传参数的,必须在装饰器之前定义。且传递入装饰器内的参数值不随变量后来的的改变而改变。