装饰器

内容概要

  • 装饰器简易版本
  • 装饰器进阶版本
  • 装饰器练习(认证功能)
  • 装饰器固定模板
  • 装饰器语法糖
  • 有参装饰器

装饰器简易版本

  • 给函数添加统计执行时间的功能
    import time

    def index():
    time.sleep(1)
    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()
    image

解决参数问题

  • import time

    def index():
    time.sleep(1)
    print('嘿嘿嘿')

    def login(name):
    time.sleep(1)
    print('%s正在发牌' % name)

    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('sss')
    index = outer(index)
    index()
    image

解决返回值问题

  • import time

    def login(name):
    time.sleep(1)
    print('%s正在发牌' % name)
    return 'from login'

    def outer(func): # 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函数名返回出去

    login = outer(login)
    res1 = login('sss')
    print(res1)
    image

认证装饰器

  • import time
    def index():
    time.sleep(1)
    print('锄禾日当午')
    def home():
    time.sleep(1)
    print('汗滴禾下土')
    def register():
    time.sleep(1)
    print('注册功能')
    # 给index函数添加认证功能
    """
    在调用index之前需要用户输入用户名和密码
    正确才可以调用
    错误直接拒绝
    """
    # 定义一个用于记录用户是否登录的数据
    is_login =

    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 == 'jason' 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()

装饰器固定模板

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

装饰器语法糖

  • 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')
    """
    装饰器语法糖是写规范
    语法糖必须紧贴在被装饰对象的上方
    装饰器语法糖内部原理
    会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用
    """

双层语法糖

  • 统计函数运行时间
    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 == 'jason' 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()

装饰器修复技术

  • 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)
    image

三层语法糖

  • 判断七句print执行顺序
    def outter1(func1):
    print('加载了outter1')
    def wrapper1(args, **kwargs):
    print('执行了wrapper1')
    res1 = func1(
    args, **kwargs)
    return res1
    return wrapper1

    def outter2(func2):
    print('加载了outter2')
    def wrapper2(args, **kwargs):
    print('执行了wrapper2')
    res2 = func2(
    args, **kwargs)
    return res2
    return wrapper2

    def outter3(func3):
    print('加载了outter3')
    def wrapper3(args, **kwargs):
    print('执行了wrapper3')
    res3 = func3(
    args, **kwargs)
    return res3
    return wrapper3

    @outter1
    @outter2
    @outter3
    def index():
    print('from index')

有参装饰器

  • def outer(source_data):
    # source_data = 'file'
    def login_auth(func):
    def auth(*args,**kwargs):
    # 2.校验用户名和密码是否正确
    # 数据的校验方式可以切换多种
    if source_data == 'file':
    # 从文件中获取用户数据并比对
    print('file文件获取')
    elif source_data == 'MySQL':
    # 从MySQL数据库中获取数据比对
    print('MySQL数据库获取')
    elif source_data == 'postgreSQL':
    # 从postgreSQL数据库中获取数据对比
    print('postgreSQL数据库获取')
    else:
    print('用户名或密码错误 无法执行函数')
    return auth
    return login_auth

    @outer('file')
    def index():
    print('from index')
    @outer('MySQL')
    def home():
    print('from home')

    index()
    home()
    image

image

posted @ 2021-11-17 15:08  一览如画  阅读(52)  评论(0)    收藏  举报