Welcome to kimi's blog

函数(多层语法糖,有参装饰器、递归函数)

函数

装饰器语法糖

"""装饰器语法糖,语法糖会自动将下面紧挨着的函数当作第一个参数自动传给@函数调用"""
    def outer(func):
        def inner(*args,**kwargs):
            print('执行被装饰对象之前可以做的额外操作')
            res = func(*args,**kwargs)
            print('执行被装饰对象之后可以做的额外的操作')
            return res
        return inner

    @outer
    def func():
        print('和叶')
        return 'func'

    @outer
    def func1():
        print('和花')
        return 'func1'

    func()
    func1()

多层语法糖

​ 语法糖的结构如下

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

    index()

    """ 多层语法糖 加载顺序由下往上,
    每次执行之后,如果上面还有语法糖,则直接将返回值函数传给上面的语法糖,
    如果上面没有语法糖了,则变形index= outter1(wrapper2)
    """

语法糖解析顺序如下

image

有参装饰器

# 校验用户是否登录装饰器
    def outer(mode):
        def login_auth(func):
            def inner(*args,**kwargs):
                username = input('please input your name>>:').strip()
                password = input('please input your pwd>>:').strip()
                if mode == '1':
                    print('数据直接写死')
                elif mode == '2':
                    print('数据来源于文本文件')
                elif mode == '3':
                    print('数据来源于字典')
                elif mode == '4':
                    print('数据来源于MySQL')
                # res = func(*args,**kwargs)
                # return res
            return inner
        return login_auth

    # @outer('1')
    # def index():
    #     print('from index')
    # index()  # 数据直接写死
    # @outer('2')
    # def index():
    #     print('from index')
    # index()      # 数据来源于文本文件
    @outer('3')
    def index():
        print('from index')
    index()  # 数据来源于字典

装饰器模板

最常用的无参模板

    """无参装饰器"""
    def outer(func):
        def inner(*args,**kwargs):
            print("在执行被装饰对象之前可以做的额外的操作")
            res = func(*args,**kwargs)
            print("在执行被装饰对象之后可以做的额外的操作")
            return res
        return inner

    @outer
    def index():
        pass

不常用的有参装饰器

    def outer_plus(mode):
        def outer(func):
            def inner(*args,**kwargs):
                print("在执行被装饰对象之前可以做的额外的操作")
                res = func(*args,**kwargs)
                print("在执行被装饰对象之后可以做的额外的操作")
                return res
            return inner
        return outer

    @outer_plus('MySQL')
    def index():
        pass

装饰器修复技术

help函数名来查看函数的文档注释,本质就是查看函数的_doc_属性。但被装饰之后的函数,查看文档注释

    """help的用法"""
    def index():
        pass

    help(index) 

    """打印结果:
     Help on function index in module __main__: index()
    """

    help(len)

    """打印结果:
    # Help on built-in function len in module builtins: 
    len(obj, /)  
    Return the number of items in a container.
    """
 

引入了functools模块下提供一个装饰器wraps专门来我们实现

   
   from functools import wraps
    def outer(func):
        @wraps(func)  # 仅仅时为了让装饰器的效果更加逼真,平时不用写
        def inner(*args,**kwargs):

            """  我是inner 我擅长让人蒙蔽"""
            res = func(*args,**kwargs)
            return res
        return inner

    @outer
    def index():
        """我是真正的index"""
        pass


    help(index)
    help(index)

    index()

递归函数

1.函数的递归调用

​ 函数直接或者间接的调用了函数自身

​ 1.1直接调用

# 直接调用
    def index():
        print('from index')
        index()

    index()

​ 1.2间接调用

# 间接调用
    def index():
        print('from index')
        func()

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

    func()

2.最大递归深度

eg:
    count = 0
    def index():
        global count
        count += 1
        print(count)
        index()

    index()   # 1-996
    
    """ 最大递归深度:python解释器添加的安全措施"""
    """ 官网提供的最大递归深度为1000,我们在测试的时候可能会出现996、997、998"""

3.递归函数

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,]]]]]]]]

方法1

def func(a):
    for i in a:
        if type(i) is int:
            print(i)
        else:
             return func(i)

func(l1)



方法2
def func(a):
    for i in a:
        if isinstance(i,int):
            print(i)
        else:
            return func(i)

func(l1)

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


dict_list = {'1':{'name':'kiki','password':"123"},
            '2':{'name':'kimi','password':"456"}}

def outer_plus(mode):

    def outer(func):
        def inner(*args,**kwargs):
            username = input('please input your name>>:').strip()
            password = input('please input your pwd>>:').strip()

            if mode == '1':
                print('数据直接写死')
            elif mode == '2':
                with open(r'a.txt','r',encoding='utf8') as f:
			for line in f:
                        real_name,real_pwd = line.split('|')
                        if username == real_name and password == real_pwd.strip('\n'):
                            print('数据来源于文本文件')
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('用户名不存在')

            elif mode == '3':
                for i in dict_list:
                    if dict_list[i]['name'] == username and dict_list[i]['password']==password:
                        print('数据来源于字典')

                        res = func(*args, **kwargs)
                        return res
                else:
                    print('用户名不存在')

            elif mode == '4':
                print('数据来源于MySQL')
            res = func(*args,**kwargs)
            return res
        return inner
    return outer


@outer_plus('3')
def index():
    print('校验成功')
index()
posted @ 2022-10-12 21:11  魔女宅急便  阅读(27)  评论(0)    收藏  举报
Title