函数装饰器

函数装饰器

1.装饰器简易版本

给函数添加统计时间的功能

import time
def index()
		time.sleep(3)
		print('原函数')
def outer(func):  # func指向的是函数名index
    # func = index
    def get_time():
        start_time = time.time()
        func()
        end_time = time.time()
        print('函数运行时间:%s' % (end_time - start_time))
    return get_time  # 将get_time函数名返回出去
index = outer(index)  # outer(index函数名)
# 左侧的变量名index指代是函数名get_time
index()
      	

2.解决参数问题

import time
def index():
    time.sleep(3)
    print('函数1')
def login(num):
    time.sleep(1)
    print('函数%s'%num)
def outer(func):  # func指向的是函数名login
    # func = login
    def get_time(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        end_time = time.time()
        print('函数运行时间:%s' % (end_time - start_time))
    return get_time  # 将get_time函数名返回出去
login = outer(login)
login('2')
index = outer(index)
index()

3.解决返回值问题

# 接收原函数的返回值
import time
def index():
    time.sleep(3)
    print('函数1')
    return 'from index'
def login(num):
    time.sleep(1)
    print('函数%s'% num)
    return 'from login'
def outer(func):  # func指向的是函数名login
    # func = login
    def get_time(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)  # 接收被装饰函数的返回值
        end_time = time.time()
        print('函数运行时间:%s' % (end_time - start_time))
        return res  # 执行完get_time之后返回被装饰函数执行之后的返回值
    return get_time  # 将get_time函数名返回出去
index = outer(index)
res = index()
print(res)
login = outer(login)
res1 = login('1')
print(res1)

4.认证装饰器

import time
def index():
    time.sleep(1)
    print('百万大奖等你来拿 赶快加入我们吧!!!')
def home():
    time.sleep(1)
    print('学学学 一天到晚就是学 卷死你们这些家伙')
def register():
    time.sleep(1)
    print('注册功能')
# 给index函数添加认证功能

"""
在调用index之前需要用户输入用户名和密码
    正确才可以调用
    错误直接拒绝
"""
# 定义一个用于记录用户是否登录的数据
is_login = {'is_login':False}


def login_auth(func):
    def auth(*args,**kwargs):
        # 1.1 先判断用户是否已经登录
        if is_login.get('is_login'):
            # 3.正常执行函数index
            res = func(*args, **kwargs)
            return res
        # 1.先获取用户的用户名和密码
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        # 2.校验用户名和密码是否正确
        if username == 'tony' and password == '123':
            # 3.正常执行函数index
            res = func(*args,**kwargs)
            # 4.将记录用户登录状态的数据修改
            is_login['is_login'] = True
            return res
        else:
            print('用户名或密码错误 无法执行函数')
    return auth
index = login_auth(index)
index()
home = login_auth(home)
home()
register = login_auth(register)
register()

5.装饰器固定模版

def outer(func):
  	def inner(*args,**kwargs):
      	print('执行函数之前可以添加的额外功能')
        res = func(*args,**kwargs)  # 执行被装饰的函数
        print('执行函数之后可以添加的额外功能')
        return res  # 将被装饰函数执行之后的返回值返回
    return inner
  

6.装饰器语法糖

​ 装饰器语法糖是写规范
​ 语法糖必须紧贴在被装饰对象的上方
​ 装饰器语法糖内部原理
​ 会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用

def outer(func):
    def inner(*args, **kwargs):
        print('执行函数之前可以添加的额外功能')
        res = func(*args, **kwargs)  # 执行被装饰的函数
        print('执行函数之后可以添加的额外功能')
        return res  # 将被装饰函数执行之后的返回值返回
    return inner
@outer  # index = outer(index)
def index(*args, **kwargs):
    print('from index')
@outer  # home = outer(home)
def home():
    print('from home')

7.双层语法糖

import time
def get_time(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)  # 执行被装饰的函数
        end_time = time.time()
        print('函数执行时间:%s'%(end_time-start_time))
        return res  # 将被装饰函数执行之后的返回值返回
    return inner
# 校验用户登录装饰
def login_auth(func):
    def inner(*args, **kwargs):
        # 1.先获取用户的用户名和密码
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        # 2.校验用户名和密码是否正确
        if username == 'tony' and password == '123':
            res = func(*args, **kwargs)  # 执行被装饰的函数
            return res  # 将被装饰函数执行之后的返回值返回
        print('用户名或密码错误 无权限执行')
    return inner
@login_auth  # 上面没有语法糖之后就用被修饰的函数名接受
@get_time  # 先从下面的开始执行
def index():
    time.sleep(1)
    print('from index')
index()

image

8.装饰器修复技术

from functools import wraps
def outer(func):
    @wraps(func)  # 修复技术就是为了让被装饰对象更加不容易被察觉装饰了
    def inner(*args, **kwargs):
        print('执行函数之前可以添加的额外功能')
        res = func(*args, **kwargs)  # 执行被装饰的函数
        print('执行函数之后可以添加的额外功能')
        return res  # 将被装饰函数执行之后的返回值返回
    return inner


@outer  # index = outer(index)
def index():
    print('from index')
print(index)
help(index)

def home():
    """这是一个home函数"""
    print('from home')
# help(index)
# help(home)
# print(index)
# help(len)
posted @ 2021-11-17 20:25  skuukzky  阅读(76)  评论(0)    收藏  举报