装饰器、生成器

装饰器主要用于程序功能的一些扩展。

由于在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),这种变量名传参数的,必须在装饰器之前定义。且传递入装饰器内的参数值不随变量后来的的改变而改变。

原文地址:https://www.cnblogs.com/ohahastudy/p/8127554.html