首页 > 其他 > 详细

装饰器,迭代器,生成器

时间:2020-02-10 17:38:07      阅读:65      评论:0      收藏:0      [点我收藏+]

1. 装饰器

定义: 在函数运行前或运行后可以添加额外功能且不影响该函数原有的代码功能,并且还可以进行函数执行后的清理工作。

语法

语法:
@func1
def func2():
    pass
装饰器做得事情就是func1(func2)我们传递了一个函数对象到我们的装饰器里面然后先执行装饰器func1其中的内容,然后再执行函数func2

三类装饰器

1.普通无参装饰器

def wai(func):      # func 被装饰函数
    def nei():   # a,b 表明被装饰函数的参数
        print('函数执行前添加')
        res = func()
        print('函数执行后添加')
        return res    # 内层函数将外层函数调用的被装饰函数作为参数返回
    return nei    # 外层函数返回内层函数的函数名

@wai
def func():
    print("这是一个函数")
    return 1
func()

2.被装饰函数带参数

def wai(func):      # func 被装饰函数
    def nei(a,b):   # a,b 表明被装饰函数的参数
            a = a + 1
            b = b + 1
            print('函数执行前添加')
            res = func(a,b)
            print('函数执行后添加')
            return res    # 内层函数将外层函数调用的被装饰函数作为参数返回
    return nei    # 外层函数返回内层函数的函数名
@wai
def func(a,b):
    print("这是一个函数")
    return a+b
res = func(1,2)
print(res)

3.装饰器函数有参数

def f(is_ok):     # 在装饰器函数设置参数如果条件成立执行
    def wai(func):      # func 被装饰函数
        def nei(a,b):   # a,b 表明被装饰函数的参数
            if is_ok:
                a = a + 1
                b = b + 1
                print('函数执行前添加')
                res = func(a,b)
                print('函数执行后添加')
                return res    # 内层函数将外层函数调用的被装饰函数作为参数返回
            else:
                return func(a,b)
        return nei    # 外层函数返回内层函数的函数名
    return wai
@f(is_ok=0)
def func(a,b):
    print("这是一个函数")
    return a+b
res = func(1,2)
print(res)

2. 生成器

定义: 生成器是特殊的迭代器,生成器自动实现了迭代器协议(iter,next), 不需要手动维护这两种方法。

元组推导式

ge = (var for var in range(10))

调用生成器的两种方式(next(ge), ge.__next__(),在生成器next()下一个值时,到最后一个就会报出异常(StopIteration))

该表达式可以在处理大量数据保存在序列时,比较费内存,而当前的生成器方式可以延迟生产数据,节约内存。而数据只有在需要的生产。

[生成器的好处,在需要它的时候再进行next()取出,比较节省内存,再python2中都在列表中占用内存比较大]

生成器--函数实现生成器

重点:如果在函数中出现了yield关键字,该函数将不在是普通函数,而是生成器函数。

return:函数中起到 返回并且终止函数
yield: 函数中起到 返回并且挂起函数
def gen():
    # return: 返回并且终止函数
    # yield:  返回并且挂起函数
    # next: 下一个(唤醒)--> yield  return
     for i in range(10):
         yield i

a = gen()
res = next(a)
print(a)
print(res)
res = next(a)
print(res)

生成器创建后有三个方法

  • 1.close() 在指定的位置可以手动关闭生成器函数,会使后面的生成器使用直接返回Stoplteration 异常
def gen():
    # return: 返回并且终止函数的作用
    # yield:  返回并且挂起函数的作用
    # next: 下一个(唤醒)--> yield  return
    for i in range(10):
        yield i
a = gen()
res = next(a)
print(a)
print(res)
res = next(a)
print(res)
a.send(11)
# a.close()    # 关闭生成器  关闭后相当于抛出StopIteration异常
  • 2.send() 生成器函数可以接受一个外部传入的变量,并且可以像函数处理参数一样将这个变量在运行期间进行处理并返回;在使用send函数时,
    第一次首先需要传入None或next函数调用的形式将生成器第一个值生产。
def gen():
    num = 0
    while True:
        var = yield num      # 将num赋给var,a.send() 传进来的值在这里
        yield num
        num += var
a = gen()
res = next(a)
print(a)
print(res)
a.send(10)     # 向函数传递参数值

res = next(a)
print(res)
  • 3.throw() 用来像生成器函数传入一个异常,使生成器结束,可以自己定义其位置。
def gen():
    num = 0
    while True:
        var = yield num      # 将num赋给var,a.send() 传进来的值在这里
        yield num
        num += var
a = gen()
res = next(a)
print(a)
print(res)
a.send(10)     # 向函数传递参数值
res = next(a)
print(res)
a.send(11)
a.throw(ValueError)   # 可以自定义抛出异常,抛出异常的类型
res = next(a)
print(res)

3.迭代器

迭代器与Python2.2版本后添加,他为类序列对象提供了一个可以使其进化为迭代器的接口 iter

迭代器对象内部会维持一个状态,用于记录当前迭代的状态,以方便下次迭代时提取正确的数据元素

可迭代对象内置__iter__函数,该函数将对象处理为可迭代对象

任何实现__iter__和__next__的对象都可看作迭代器

__iter__返回迭代器自身、__next__返回迭代的下个值    

迭代器没有返回的元素,抛出StopIteration

可以直接利用的迭代器

无限迭代器生产:
    无限迭代器
        from itertools import count
    有限数据对象晋升为无限迭代器
        from itertools import cycle
有限迭代器生产:
    iter()
    from itertools import islice
    islice(iterable, stop)
    islice(iterable, start, stop[, step])

自定义迭代器

自定义迭代器:__iter__()、__next__()

自定义迭代器实现斐波那契

# 迭代器实现斐波那契
class Func():
    def __init__(self):
        self.prev = 0
        self.curr = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.curr
        self.curr += self.prev      # 当前值 等于上一次的当前值 加上一次的上一次的值
        self.prev = value
        return value

if __name__ == '__main__':
    f = Func()
    print(next(f))
    print(next(f))

总结

使用迭代器不要求事先准备好整个迭代过程中的所有元素。

迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后元素可以不存在或者被销毁。

因此迭代器只能往前,不能后退适合遍历一些数量巨大甚至无限的序列。

装饰器,迭代器,生成器

原文:https://www.cnblogs.com/xinzaiyuan/p/12284592.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!