zoukankan      html  css  js  c++  java
  • 闭包函数与迭代器生成器

    闭包函数

    闭包函数定义

    • 必须是函数内嵌函数

    • 内嵌函数必须引用外函数的变量

    • 外函数返回内嵌函数的函数名

    def otter():
        name = 'Gredae'
        def inner():  # 外层函数包了个内层函数
            print(name)  # 内层函数引用了外层函数的变量
        return inner  # 外层函数返回内层函数的函数名
    f = otter()  # 用f变量来接收inner函数的地址
    f()  # 实际上是调用inner()函数
    

    闭包函数的作用

    可以使用函数闭包来实现一个函数的装饰器

    函数装饰器的条件

    1. 不能改变原来函数的代码
    2. 为函数添加新的功能
    3. 不能改变函数的调用方式

    装饰器的简单使用

    计算函数运行的时间:

    import time
    def deco(func):  # func = index
        """装饰器函数"""
        def inner():
            start = time.time()
            func()  # index
            end = time.time()
            print(end - start)
        return inner
    @deco  # 如果在被装饰的函数上方写了语法糖就可以代替下面的 index = deco(index)
    def index():
        """被装饰的函数"""
        time.sleep(1)
        print('hello, index')
    
    index = deco(index)  # index = inner 如果上面写了@deco语法糖就可以代替这一行
    index()  # 实际上执行的是inner函数
    

    上面的是双层装饰器

    三层装饰器饰装饰装饰器

    def auth(engine):
        def login(func):
            def inner(*args, **kwargs):  #将可变长参数传递进来
                # 登录功能
                if engine == 'file':
                    username = input('usrename:')
                    pwd = input('pwd:')
                    if username == 'Gredae' and pwd == '123':
                        print('登录成功')
                        res = func(*args, **kwargs)  #传递不定长实参
                        return res
                    else:
                        print('登录失败')
    
                elif engine == 'db':
                    print('账号密码来自于数据库,非法请求')
    
            return inner
        return login
    
    @auth('file')  # 三层装饰可以使用语法糖来传值
    def login():
        print('欢迎你!')
    
    login() # inner()
    

    迭代器

    更新换代, 重复, 基于上一次的结果推出下一次的结果

    迭代:具有__iter__方法

    可迭代 不可迭代
    字符串、列表、字典、元祖、集合、文件 数值对象、函数

    例如:

    s = 'Gredae'
    s_iter = s.__iter__()
    print(s_iter.__next__())  # G  ## 基于索引(基于上一次结果)通过__next__进行迭代
    print(s_iter.__next__())  # r
    print(s_iter.__next__())  # e
    print(s_iter.__next__())  # d
    

    迭代器对象:具有__iter__以及__next__方法

    迭代对象除了文件是迭代对象之外都不属于迭代对象

    迭代循环——for循环(解决了不依赖索引取值)

    lt = [1,2,3,4]
    lt_iter = lt.__iter__()  ## 也可以这样定义迭代对象: lt_iter = iter(lt)
    while True:
        try:
            print(lt_iter.__next__())  ##这句话一定会报错 也可以这样迭代: next(lt_iter)
        except StopIteration:  ## 当lt_iter迭代到没有元素的时候就会报错
            break
    
    for i in lt:   # 可迭代对象;迭代器对象  # 不依赖索引取值,而是迭代取值
        print(i)
    
    1. 首先使用iter把lt变成迭代器对象;对于文件也要使用iter方法吧文件再一次iter下
    2. 然后使用next方法进行迭代取值
    3. 判断StopIteration异常,遇到异常终止

    迭代器对象一定是可迭代对象; 可迭代对象不一定是迭代器对象

    生成器

    在 Python 中,使用了 yield 的函数被称为生成器(generator)

    跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器

    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

    例如,可以使用生成器生成一个斐波那契数列

    def fibonacci(n):  # 生成器函数 - 斐波那契
        '''生成斐波那契'''
        a, b, counter = 1, 1, 0
        while counter < n:
            yield a
            a, b = b, a + b
            counter += 1
            
    f = fibonacci(10)  # f 是一个迭代器,由生成器返回生成
    while True:
        try:
            print(next(f), end=" ")
        except StopIteration:
            break
    
  • 相关阅读:
    linux查看与设置主机名
    为什么用户主目录下.bash_profile没有自动执行
    sqlplus查看服务名
    linux之cp/scp命令+scp命令详解
    查看磁盘使用量
    yum源
    微软输入法删除
    Android下 ionic view 无法登录
    inline-block在ie6中的经典bug
    Apache端口配置
  • 原文地址:https://www.cnblogs.com/Gredae/p/11348021.html
Copyright © 2011-2022 走看看