闭包函数及装饰器

闭包函数:满足两点的函数都是闭包函数

1.定义在函数内部的函数

2.函数内部引用了外部函数作用域的名字

# 用闭包的方式给函数体传参:
def outter(x,y):  # 第三步,用另外一个函数将内层封装起来
    # x = 1  # 第二步,在函数my_max外部引用外部函数作用域名
    # y = 2
    def my_max():  #第一步,给函数传参
        if x > y :
            return x
        return y
    return my_max
res = outter(1,2)  # 返回的是x = 1, y = 2 时函数my_max()的函数名指向的函数体地址
print(res())  # 2  间接调用函数my_max(),并将结果返回值打印出来

 装饰器:

原则:开放封闭,对扩展开放,对修改封闭

此外,装饰器不能改变被装饰对象源代码,不能改变被装饰对象调用方式

# 补充知识点
import time  # 导入时间模块
print(time.time())  # 时间戳,表示当前时间距离1970-1-1  00:00:00相差的秒数
# 1970-1-1  00:00:00是Unix诞生的元年

time.sleep(3)  # 表示让cpu睡眠三秒,程序暂停三秒
#例子:统计index函数执行的时间
import time
def index():
    time.sleep(2)
    print('cvnifdhivusn')
start = time.time()
index()
end = time.time()
print('index run time:%s'%(end-start))

# 结果cvnifdhivusn
# index run time:2.000300168991089 休息了2秒,执行速度很快
# 装饰器简单版本
import time
def index():
    time.sleep(3)
    print('hiuehfjarh')

def outter(func):  # func = 最原始的index函数的内存地址
    def get_time():
        start = time.time()
        func()
        end = time.time()
        print('index run time:%s'%(end-start))
    return get_time
res = outter(index)  # outter(index) = get_time  返回的是get_time函数的内存地址
index = res  # 再将返回的内存地址赋值给变量index,做到以假乱真,调用方式不变的要求
index()
# 结果:hiuehfjarh
index run time:3.0003960132598877

 装饰器语法糖:会将紧挨着它的可调用对象的名字当作参数自动传入调用outter

@outter  # outter(index)
def index():
    pass

装饰器模板:

def outter(func):
    def inner(*args,**kwargs):
        print('     ')  # 执行被装饰函数之前,可以做的操作
        res = func(*args,**kwargs)
        print('   ')  # 执行被装饰函数之后,可以做的操作
        return = res
    return = inner
# 例子:认证装饰器
# 执行函数index之前必须先输入用户名和密码,正确之后才可以执行操作
# 否则提示用户输入错误,结束程序
user_dic = {'is_login':None}

def login_auth(func):
    def inner(*args,**kwargs):
        if user_dic['is_login']:  # 布尔值为False
            res = func(*args,**kwargs)
            return res
        else:
            username = input(':').strip()
            password = input(':').strip()
            if username == 'zhao' and password == '123':
                user_dic['is_login'] = True  # 账号及密码都正确则布尔值变为True
                res = func(*args,**kwargs)  # 执行函数func()并将结果用res接收
            else:
                print('username or password error')
    return inner

 多层装饰器:

装饰器在装饰的时候,顺序从下往上

装饰器在执行的时候,顺序从上往下

原文地址:https://www.cnblogs.com/pupy/p/11176723.html