装饰器


装饰器

简介:在不改变装饰对象“内部代码”的同时,

           和“原有调用方式”的基础上添加新的功能。

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

器:指的就是工具。

装饰:给被装饰对象添加的额外功能

 装饰器简易版

# 计算代码运行的时间
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
index = outer(index)
index() #最后未修改原有的调用方式及装饰对象,且实现了功能

 解决参数的问题

# 使用参数的同时使用装饰器
import time
def index():
    time.sleep(3)
    print('好好学习,天天向上')
def login(name):
    time.sleep(3)
    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
login = outer(login)
login('jason')
index = outer(index)
index()

 解决返回值问题

import time
def index():
    time.sleep(3)
    print('好好学习,天天向上')
    return 'from index'
def login(name):
    time.sleep(3)
    print('%s正在教室学习' % name)
    return 'from login'
def outer(func):   # func指向index
    # func = index
    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
    return get_time
index = outer(index)
res = index()
print(res)
login = outer(login)
res1 = login('jason')
print(res1)

 认证装饰器(一步一步慢慢来)

import time
def index():
    time.sleep(1)
    print('图书馆开馆100周年')
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):
        # 判断用户是否登入
        if is_login.get('is_login'):
            res = func(*args, **kwargs)
            return res
        # 获取用户名和密码
        username = input('用户名:').strip()
        password = input('密码:').strip()
        # 验证是否正确
        if username == 'jason' and password == '123':
            # 正常执行index
            res = func(*args,**kwargs)
            # 将记录用户登录状态的数据修改
            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
@outer  # index = outer(index)
def index(*args, **kwargs):
    print('from index')
@outer  # home = outer(home)
def home():
    print('from home')
index()

双层语法结糖 ( 了解 )

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):
        username = input('username:').strip()
        password = input('password:').strip()
        if username == 'jason' and password == '123':
            res = func(*args, **kwargs)
            return res
        print('用户名或密码错误')
    return inner
@login_auth  # index = login_auth(index)
@get_time  # index = get_time(index)
def index():   # 从下往上,一步步来
    time.sleep(1)
    print('from index')
index()

 装饰器的固定模式

def outer(func):
    def inner(*args, **kwargs):
        print('执行函数之前添加的功能')
        res = func('*args, **kwargs')
        print('执行函数之后添加的功能')
        return res
    return inner
@outer
def index(*args, **kwargs):
    print('from index')
def home():
    print('from home')
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)

相关