函数进阶版之装饰器

闭包函数简介

闭包函数:必须符合下面两个特征才能称为闭包函数

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

2.内部函数使用了外部函数名称空间中的名字;

def func(username):
    def index():
        print(username)
    return index
res = func('aaa')
print(res)
res()

# 打印结果 aaa

 装饰器简介

1.装饰器的本质

        在不改变被装饰对象原来的‘调用方式’和‘内部代码’的情况下给被装饰对象添加新的功能

2.装饰器的原则

        对修改封闭 对扩展开放

from functools import wraps
def outer(func_name):
    @wraps(func_name)
     def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
     return inner

3.知识储备

import time
print(time.time())
'''时间戳(秒数):当前距离1970年1月1日0时0分0秒所经历的秒数,可统计代码的运行时间'''
time.sleep(2)
'''让程序原地等待三秒'''

装饰器的前期推导 

import time

def index():
    time.sleep(3)
    print('from index')

def get_time():
    start_time = time.time()  # 在调用index函数之前获取一下时间戳
    index()  # 调用index函数
    end_time = time.time()
    print('函数的执行时间是:',end_time - start_time)

ps:运行上面代码如果要多个不同的函数需要统计时间的话就不够灵活。

import time

def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(5)
    print('from home')

def get_time(xxx):
    start_time = time.time()  # 在调用index函数之前获取一下时间戳
    xxx(*args,**kwargs)  # 调用index函数
    end_time = time.time()
    print('函数的执行时间是:',end_time - start_time)

get_time(index)
get_time(home)

ps:将代码优化成上述代码后可以实现统计多个不同的函数。

 装饰器各种版本 

import time

"""针对有参无参函数如何兼容"""
def outer(xxx):
    def get_time(*args, **kwargs):
        start_time = time.time()  # 在调用index函数之前获取一下时间戳
        res = xxx(*args, **kwargs)  # 调用index函数
        end_time = time.time()
        print('函数的执行时间是:', end_time - start_time)
        return res
    return get_time

def index(name):
    time.sleep(1)
    print('from index')
    return '执行index函数之后的返回值'

home = outer(home)
xxx = home()
print(xxx)

ps:上述代码在装饰器中先用一个变量把被装饰的函数返回值确定实现了对参数有误的兼容,完成了一个简易但完整的装饰器。

装饰器的固定模版

1.装饰器固定模版

        针对很多人无法快速的领悟和理解装饰器的作用,可以直接记固定模版

from functools import wraps
def outer(func_name):
    @wraps(func_name)  # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
    return inner

2.装饰器语法糖

        @ 符号就是装饰器的语法糖

import time
from functools import wraps

def outer(func_name):
    @wraps(func_name)  # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
    return inner

@outer  #  home = outer(真正的函数名home)
def home():
    '''我是home函数 我要热死了!!!'''
    time.sleep(1)
    print('from home')
    return 'home返回值'

help(home)    '''home()
                我是home函数 我要热死了!!!'''
  
print(home)   '''<function home at 0x7ff02a4d9310>
                 执行被装饰对象之前可以做的额外操作'''

home()        '''from home
                 执行被装饰对象之后可以做的额外操作'''

ps:在python中help ()函数用于查看函数或模块用途的详细说明


#### 今日作业###

1.编写一个用户认证装饰器
  基本要求
   执行每个函数的时候必须先校验身份 eg: jason 123
  拔高练习(有点难度)
   执行被装饰的函数 只要有一次认证成功 那么后续的校验都通过
     函数:register login transfer withdraw 
   提示:全局变量 记录当前用户是否认证

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值