19、函数闭包、装饰器

一 闭包函数

1 闭包函数:函数内部定义函数,成为内部函数,该内部函数包含对外部作用域,而不是对全局作用域名字的饮用,那么该内部函数成为闭包函数。

name='alex'
def func():
    name='egon'
    def bar():
        print(name)
    return bar

b=func()
print(b)
name='hahahahahahahahahahahahahahahhahahah'

2 闭包函数的特点:自带作用域

                         延迟计算

name='alex'
def func():
    def bar():
        print(name)
    return bar

f=func()
print(f.__closure__)

f()

3 定义闭包函数的基本形式

def 外部函数名():
内部函数需要的变量
def 内部函数():
引用外部变量
return 内部函数
例如:
def deco():
    x=1
    def wrapper():
        print(x)

    return wrapper

wrapper=deco()

print(wrapper)

4 包一层

def wrapper():
    money=1000
    def tell_info():
        print('egon have money %s' %(money))
    return tell_info

tell_info=wrapper()

def foo():
    money=100
    tell_info()

foo()

5 包二层

def aaa():
    name='egon'
    def wrapper():
        money=1000
        def tell_info():
            print('egon have money %s' %(money))
            print('my namn is %s' %name)
        return tell_info
    return wrapper

w=aaa()
tell_info=w()
print(tell_info.__closure__[0].cell_contents)
print(tell_info.__closure__[1].cell_contents)

二 装饰器

1 开放封闭原则,对扩展是开放的,对修改是封闭的

2 装饰器的本质是可以任意调用对象,被装饰的对象也可以是任意可调用对象。

3 装饰器的功能:在不修改被装饰对象源代码以及调用方式的前提下为其添加新功能

   原则:1.不修改源代码    2.不修改调用方法

   

例:

import time
import random
#装饰器
def timmer(func):
    # func=index
    def wrapper():
        start_time = time.time()
        func() #index()
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
    return wrapper
#被装饰函数
def index():
    time.sleep(random.randrange(1,5))
    print('welecome to index page')

def home():
    time.sleep(random.randrange(1,3))
    print('welecome to HOME page')

index=timmer(index) #index=wrapper
home=timmer(home)

index() #wrapper()

4 装饰器的语法:在被装饰对象的正上方的单独一行,@+装饰器名字

例:
import time
import random
#装饰器
def timmer(func):
    def wrapper():
        start_time = time.time()
        func()
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
    return wrapper
#被装饰函数
@timmer #index=timmer(index)
def index():
    time.sleep(random.randrange(1,5))
    print('welecome to index page')
@timmer #home=timmer(home)
def home():
    time.sleep(random.randrange(1,3))
    print('welecome to HOME page')

index() #wrapper()
home()