day23

闭包函数

定义

闭包函数把 闭包函数内部的变量+闭包函数内部的函数包在一起 然后通过返回值得形式返回出来

def f1():
    def f2():
        pritn('from f2')
        
    return f2
f2 = f1()
f2()

闭包函数嵌套

闭包函数也符合函数嵌套

def f1(url): # f1就叫做闭包函数
    def f2():
        print(url)
        pass
        
    return f2 # 函数对象
res = f1(1)
res()

装饰器

本质

一个 给函数增加功能的函数

注意

  1. 装饰器本身是函数,只不过用来装饰 被装饰的函数
  2. 不改变原函数的源代码
  3. 不改变原函数的调用方式

计时功能的装饰器

# v1
import time

def index():
    """被装饰的函数"""
	print('index')
    time.sleep(1)
# time_count 装饰器:对被装饰函数计时
def time_count(func): # func 才是真正的index
    """装饰器"""
    
    def wrapper():
        start = time.time()
        func()
        end = time.time()
        print(end - start)
        
    return wrapper

index = time_count(index) # index == wrapper
index() # wrapper()

带返回值

# v2:带返回值
import time

def index():
    """被装饰的函数"""
	print('x', x)
    print('index')
    time.sleep(1)
    
    return 'index'
# time_count 装饰器:对被装饰函数计时
def time_count(func): # func 才是真正的index
    """装饰器"""
    
    def wrapper():
        start = time.time()
        res = func() # index()
        end = time.time()
        print(end - start)
        
        return res
    
    return wrapper

index = time_count(index) # index == wrapper
res = index() # wrapper()
print(res)

加参数

# v3:加参数
import time


def index(x,y,z=10):
    """被装饰的函数"""
    print('x',x)
    print('index')
    time.sleep(1)

    return 'index'


# time_count装饰器:对被装饰函数计时
def time_count(func):  # func才是真正的index
    """装饰器"""

    def wrapper(*args,**kwargs):  # (10, 20)  # *args和**kwargs接收了所有的参数
        start = time.time()
        res = func(*args,**kwargs)  # index()  # *(10,20)  # *args和**kwargs打散参数传给真正的index
        end = time.time()
        print(end - start)

        return res

    return wrapper


index = time_count(index)  # index == wrapper
res = index(10,20,320)  # wrapper()
print(res)

登录装饰器

username_list = []


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('user_info.txt', 'r', encoding='utf8') as fr:
            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


@login_deco  # index = login_deco(index)
def index(x, y):
    print('index')
    print('x,y', x, y)

    return 123


res = index(10, 20)

二层装饰器

  1. 用来装饰函数的,它本质是函数
  2. 不改变函数源代码
  3. 不改变函数调用方式

装饰器模板

如果装饰器真的不懂,记住模板

def deco(func):
    def wrapper(*args, **kwargs):
        # 要加什么功能就加上去
        res = func(*args, **kwargs)
        
        return res
    
    return wrapper

三层装饰器

username_list = []


def sanceng(role): # 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:
                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('admin')
def index(x, y):
    print('index')
    print('x,y', x, y)

    return 123


res = index(10, 20)

迭代器引入

可迭代对象

含有__iter__方法的就叫做可迭代对象

迭代器

含有__iter____next__方法的就叫做迭代器

生成器

含有 yield 关键字的函数就叫做生成器

posted @ 2019-09-23 19:21  Isayama  阅读(153)  评论(0编辑  收藏  举报