装饰器

今日内容总结

多层语法糖

多层语法糖>>>:加载顺序由下而上

每次执行之后如果上面还有语法糖 则直接将返回值函数名传给上面的语法糖

如果上面没有语法糖了 则变形 index = outer1(wrapper2)

def outer1(func1):  # func1 = wrapper2
    print('加载了outer1')
    def wrapper1(*args, **kwargs):
        print('执行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

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

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


@outer1  # index = outer1(wrapper2) 返回值是wrapper1
@outer2  # outer2(wrapper3) 返回值是wrapper2
@outer3  # outer3(index函数) 返回值是wrapper3
def index():
    print('666')

index()

image

有参装饰器

# 校验用户是否登录装饰器
def outer(mode):
    def login_auth(func_name):
        def inner(*args, **kwargs):
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            if mode == '1':
                print('跟定义好的结果比对 数据值直接写死')
            elif mode == '2':
                print('打开文本文件 一行行读取比对')
            elif mode == '3':
                print('跟提前定义好的字典 比对')
            elif mode == '4':
                print('数据来源于MySQL')
        return inner
    return login_auth
"""当装饰器中需要额外的参数时>>>:有参装饰器"""
"""
函数名加括号执行优先级最高 有参装饰器的情况
    先看函数名加括号的执行
    然后再是语法糖的操作
"""
@outer('1')
def index():
    print('from index')
index()
@outer('2')
def func():
    print('from func')
func()

装饰模板器

# 最常用的无参装饰器
def outer(func_name):
    def inner(*args, **kwargs):
        res = func_name(*args, **kwargs)
        return res
    return inner
@outer
def index():
    pass

# 不常用的有参装饰器
def outer_plus(mode):
    def outer(func_name):
        def inner(*args, **kwargs):
            res = func_name(*args, **kwargs)
            return res
        return inner
    return outer
@outer_plus('MySQL')
def func():
    pass

装饰器修复技术

from functools import wraps  # 修复技术固定代码
def outer(func_name):
    @wraps(func_name)  # 仅仅是为了让装饰器的效果更加逼真
    def inner(*args, **kwargs):
        """我是inner 我擅长让人蒙蔽"""
        res = func_name(*args, **kwargs)
        return res
    return inner

@outer
def func():
    """我是真正的func 我很强大 我很牛 我很聪明"""
    pass


help(func)
print(func) 

递归函数

1.函数的递归调用
函数直接或者间接的调用了函数自身
直接调用
def index():
    print('from index')
    index()
index()
间接
def index():
    print('from index')
    func()

def func():
    print('from func')
    index()

func()
'''最大递归深度:python解释器添加的安全措施'''
count = 0
def index():
    global count
    count += 1
    print(count)
    index()
index()
'''官网提供的最大递归深度为1000 我们在测试的时候可能会出现996 997 998'''

2.递归函数
1.直接或者间接调用自己
2.每次调用都必须比上一次简单
  并且需要有一个明确的结束条件
递推: 一层层往下
回溯: 基于明确的结果一层层往上
"""
get_age(5) = get_age(4) + 2
get_age(4) = get_age(3) + 2
get_age(3) = get_age(2) + 2
get_age(2) = get_age(1) + 2
get_age(1) = 18
"""


def get_age(n):
    if n == 1:
        return 18
    return get_age(n - 1) + 2


res = get_age(5)
print(res)

作业

# 1.利用递归函数依次打印列表中每一个数据值
# l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]

l1 = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]]


def get_list(li):  # 定义一个函数 需要用户传一个列表
    for i in li:  # 遍历用户传来的列表 
        if type(i) == list:  # 判断遍历来的数据值的数据类型是否是列表
            get_list(i)  # 是列表继续调用函数并传参遍历出来的列表  递归函数
        else:
            print(i)  # 不是列表就打印出数据值

get_list(l1)



# 有参装饰器编写多种用户登录校验策略


l2 = [['qyf', '123'], ['wei', '234']]
d1 = {'qyf': {'name': 'qyf', 'pwd': '222'}, 'wei': {'name': 'wei', 'pwd': '333'}}


def outer(a):
    def login_auth(func):
        def inner(*args, **kwargs):
            username = input('请输入用户名:').strip()
            password = input('请输入密码:').strip()
            if a == '1':
                if username == 'qyf' and password == '123':
                    print('登陆成功')
                    res = func(*args, **kwargs)
                    return res
                print('用户名或密码错误')
            elif a == '2':  # 列表
                for i in l2:
                    if username == i[0] and password == i[1]:
                        print('登陆成功')
                        res = func(*args, **kwargs)
                        return res
                print('用户名或密码错误')
            elif a == '3':  # 字典
                if username in d1:
                    b = d1.get(username)
                    name, pwd = b.values()
                    if username == name and password == pwd:
                        print('登陆成功')
                        res = func(*args, **kwargs)
                        return res
                print('用户名或密码错误')
            elif a == '4':
                with open('text', 'r', encoding='utf8') as f:
                    for i in f:
                        name, pwd = i.strip().split('|')
                        if username == name and password == pwd:
                            print('登陆成功')
                            res = func(*args, **kwargs)
                            return res
                    print('用户名或密码错误')
            else:
                print('没有')
        return inner
    return login_auth


@outer('3')
def login():
    print('登录功能')


login()



posted @ 2022-10-12 19:57  小白峰  阅读(26)  评论(0)    收藏  举报