Atopos

导航

函数之装饰器

函数之装饰器

1.装饰器简易版本

给函数添加统计时间的功能
import time
def index():
    time.sleep(3)
    print('将被装饰的代码')
def home():
    time.sleep(1)
    print('第二个')

# 1.定义一个函数outer
def outer(func):
    # func = index
    def get_time():# 6.调用函数get_time
        start_time = time.time()# 7.执行计算开始时间代码
        func()# 8.这时func在函数get_time内找不到 只能向上函数outer要形参 这时函数outer形参已经传入实参index 好了现在func就是函数index 函数遇到()就调用
        end_time = time.time()# 9.执行计算结束时间代码
        print('将被装饰的代码运行时间:%s' % (end_time - start_time))# 10.打印出函数index的运行时间
    return get_time # 3.调用outer函数后返回get_time函数名到外部

'''2.将函数名index当作实参传给outer函数
   2.1再将outer函数赋值给变量名index
   2.2调用函数outer
'''
index = outer(index)# 4.outer函数调用后的返回值get_time函数名已经赋给变量名index
index()# 5.这时变量名index已经变成get_time函数名 函数名+()就调用函数 意味着这时在调用get_time函数
home = outer(home)
home()

image

2.修改参数问题

import time
def index():
    time.sleep(3)
    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('jason')
index = outer(index)
index()

image

3.解决返回值问题

import time
def index():
    time.sleep(3)
    print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!')
    return 'from index'
def login(name):
    time.sleep(1)
    print('%s正在发牌'%name)
    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('jason')
print(res1)

image

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

image

image

5.装饰器模板

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

6.装饰器语法糖

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

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')

image

7.有参装饰器

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

posted on 2021-11-17 22:19  Atopos_q  阅读(16)  评论(0)    收藏  举报