函数之 闭包函数 和 装饰器

函数的进阶一

1. 闭包函数

  • 闭包函数:闭包函数把闭包函数内部的变量 +闭包函数内部的函数 这两者包裹在一起,然后通过返回值的形式返回处来。

    这样一来,就能在全局进行对闭包函数内部的函数的调用

  • 闭包函数至少得符合函数的嵌套

def f1(url):  #f1就是闭包函数
    def spider():
        print(url)
    return spider  #函数对象
taobao = f1('www.taobao.com') #这里的 taobao 就是函数 spider
taobao() #打印结果: www.taobao.com

2 .装饰器

(1)二层装饰器

  • 装饰器就是对闭包函数的高级应用

  • 装饰器的性质和特点:

    • 装饰器的本质就是一个函数

    • 装饰器的功能就是给被装饰的函数增加功能,增加功能是必须满足一下两点

      1. 不改变被装饰函数的源代码
      2. 不改变被装饰函数的调用方式(就是说以前用 f1() 调用,装饰之后还用 f1() 调用,被装饰函数有多少形参,装饰后,调用f1()时,其括号中也得有多少实参,不能多也不能少)
  • 下面的例子是登陆装饰器

def zhuangshi(func):  # 接收到值后,func 就是函数: hanshu
    def login(*args, **kwargs):
        while True:
            user_inp = input('请输入用户名:')
            pwd_inp = input('请输入密码:')
            with open('user_info.txt', 'r', encoding='utf8')as fr:
                for user_info in fr:

                    user_name, pwd = user_info.strip().split(':')
                    if user_inp == user_name and pwd_inp == pwd:
                        print('登陆成功')
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('登录失败')

    return login


@zhuangshi  # 双层装饰器,实现了:hanshu = zhuangshi(hanshu),必须放在被装饰函数的上一行
def hanshu(x, y):
    return x + y

print(hanshu(10, y=20))

(2)三层装饰器

  • 就是在双层的外面再加一层函数

    在下面再return 一次第二层函数

  • 三层装饰器实现了向装饰器中传参事物功能

username_list = []
def sanceng(role):
    def login_deco(func):
        def wrapper(*args, **kwargs):
            if username_list:
                print('已经登录,请勿重复登录')
                res = func(*args, **kwargs)
                return res
            username_inp = input('请输入用户名:')
            pwd_inp = input('请输入密码:')

            with open(f'{role}_info.txt', 'r', encoding='utf8') as fr: #选课系统中判断是哪一种登陆 :role为老师、学生和管理员
                for user_info in fr:
                    username, pwd = user_info.strip().split(':')
                    if username_inp == username and pwd_inp == pwd:
                        print('登录成功')
                        username_list.append(username)

                        res = func(*args, **kwargs)
                        return res
                else:
                    print('登录失败')
    
        return wrapper
    return login_deco

@sanceng('user')
def index(x, y):
    print('index')
    print('x,y', x, y)
    return 123

res = index(10, 20)
print(res)

(3)装饰器模板

# 二层装饰器模板
def deco(func):
    def wrapper(*args, **kwargs):
        # 要加什么功能就加上去
        res = func(*args, **kwargs)

        return res

    return wrapper
posted @ 2019-09-23 13:51  BigSun丶  阅读(131)  评论(0编辑  收藏  举报