多重语法糖-递归函数

函数进阶

多重语法糖

1.什么是多重语法糖结构?
  就是一个函数调用了多个装饰器。

2.多重语法糖代码讲解
def outter1(wrapper2): #wrapper2
    print('加载了outter1')   # 8.此代码被执行

    def wrapper1(*args, **kwargs) :# 11.此函数被执行
        print('执行了wrapper1')     
        res1 = wrapper2(*args, **kwargs)  #12.wrapper2被执行
        return res1   
    return wrapper1    # 9.此代码被执行


def outter2(func2): #wrapper3
    print('加载了outter2')    # 5,此代码被执行

    def wrapper2(*args, **kwargs):  #13.此函数被进行
        print('执行了wrapper2')    
        res2 = func2(*args, **kwargs)  # 14.wrapper3被执行
        return res2
    return wrapper2     # 6.此代码生效


def outter3(func3):    # index
    print('加载了outter3')    #2.执行此代码 

    def wrapper3(*args, **kwargs):  # 15.此函数代码执行
        print('执行了wrapper3') 
        res3 = func3(*args, **kwargs)   # 16.index被执行
        return res3
    return wrapper3    #3.执行此代码 返回值 wrapper3

# 这里有3个语法糖
#如果上面没有了语法糖 则变形,index = outter1(wrapper2)
@outter1   # 7,因为拿到了返回值所以立刻被执行 outter1(wrapper2):
@outter2   # 4.因为拿到了返回值所以立刻被执行 outter2(wrapper3):
@outter3   # 1.执行outter3(index):  语法糖会获取下面最近的函数名执行
def index():
    print('from index')   # 17,被执行
index()    # 10 执行index(wrapper1)  
 
!!!多重语法糖执行顺序,装饰器由下至上运行 先执行 @outter3 - @outter2-@outter1 !!!

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

有参装饰器

1.什么是有参装饰器
  当装饰器中需要有额外的参数时 需要给装饰器传参时。
  
2.代码讲解
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()#'数据来源于文本文件'

装饰器模板

1.常用装饰器模板 无参装饰器
def 装饰器名字(func_name):
  def inner(*regs,**kwregs):
    #新增功能
    res = func_name(*regs,**kwregs)
    return res
  return inner

@装饰器名字
def func_name():
  pass
func_name()


2.有参装饰器模板
def 最外层装饰器(mode):
  def 装饰器名称(func_name):
    def inner(*regs,**kwregs):
      print(mode)
      res = func_name(*regs,**kwregs)
      return res
    return 装饰器名称
  return 最外层装饰器

@最外层装饰器(mode)
def func_name():
  pass
func_name()

装饰器的修复技术

# def index():
#     """index函数 非常的牛"""
#     pass
# help(index)
# help(len)
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)
func()

递归函数

1.什么是递归函数?
在函数体内直接或者间接的调用了函数本身

方法1:直接调用
def index():
  print('123')
  index()
index()
# 当我们执行函数时,函数体代码生效,但是这个函数体代码中又再次执行了函数本身,
# 所以这个就是递归函数,但是是错误的,因为他是无限循环的递归

方法2:间接调用  #在一个函数体中 可以调用另一个函数
def index():
    print('666')
    index2()


def index2():
    print('888')
    index()

index()

#当index函数运行时,运行结束会执行会调用index2,index2函数运行结束后又执行index,
#相当于,运行我结束运行你,运行你结束运行我,我们无限循环

3.什么是正确的递归函数?
  递归函数需要满足的条件:
  1.直接或者间接的调用函数自己本身
  2.每一个调用必须会上一个简单,并且要有一个明确结束的条件
    
    def get_age(n):   # 设定函数并需要传参
      if n == 1:      # 当参数为1时,返回18 
        return 18    
      return get_age(n-1)+2    # 当参数不为1时,则参数减1 +2 
    #其实已经返回了一个 get_age(4) +2 然后再循环
    
 		print(get_age(5))
      	 """
    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
    """
    #最后当拿到get_age(1) = 18  然后get_age(2)= 18+2 依次类推
    
    这就是递归函数的 递推 一层层往下,然后回溯 基于get_age(1) = 18一层层往上 

小练习

1.利用递归函数依次打印列表中每一个数据值
	l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
  
  
  def num(list):
  for i in list:
    if type(i) == int:
        print(i)
    else:
      num(i)
num(l1)


3.利用有参装饰器编写多种用户登录校验策略
# 3.利用有参装饰器编写多种用户登录校验策略
def outer(mode):
    def login_auth(func1):
        def inner(*args, **kwargs):
            username = input('请输入用户名')
            password = input('请输入密码')
            if mode == '1':
                if username == 'moon' and password == '123':
                    print('登录成功,校验来自写死数据')
                    res = func1(*args, **kwargs)
                    return res
            if mode == '2':
                dict_name = {'moon': '123'}
                if username in dict_name  and password == dict_name.get(username):
                    print('登录成功,校验来自字典')
                    res = func1(*args, **kwargs)
                    return res
            if mode == '3':
                with open('用户数据', 'r', encoding='utf8') as f:
                    for line in f:
                        r_name, r_pwd = line.split('|')
                        if username == r_name and password == r_pwd:
                            print('登录成功,效验来自文件')
                            res = func1(*args, **kwargs)
                            return res
        return inner

    return login_auth


@outer('1')
def func1():
  print('登录成功')

func1()

@outer('2')
def func2():
  print('注册')

func2()
  
posted @   Python-moon  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示