Py学习  »  Python

python迭代器、生成器装饰器(含实例学习)

执念斩长河 • 3 年前 • 179 次点击  

迭代器

迭代器从表面上看是一个数据流对象或容器,当使用其中的数据时,每次从数据流中取一个数据,直到数据被取完,而且数据不会被重复使用。

自定义迭代器

这个我单独做成一篇实例博文:
python实现设计迭代器指南(含样例启发)

内置迭代器工具

iter()

格式:

iter(iterable)
iter(callable,sentinel)
  • 1
  • 2

第一种原型中只有一个参数,要求参数为可迭代类型,当然也可以使用前文所说的各种序列类型。
第二种原型中具有两个参数,第一个参数是可调用类型,一般为函数;第二个参数被称为“哨兵”,即当第一个参数(函数)调用返回值等于第二个参数的值时,迭代器会停止迭代

例子:实现一个第二种原型迭代器,迭代出2,4,6
class Counter(object):
    def __init__(self, x=0):
        self.x = x


counter = Counter()


def used_iter():
    counter.x += 2
    return counter.x


for i in iter(used_iter, 8):
    print(i)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述

生成器

使用生成器,可以生成一个值的序列用于迭代,并且这个值的序列不是一次生成的,而是使用一个,再生成一个。

生成器创建

例子:实现递减生成器,并测试是否一次生成完毕

def myYield(n):
    while n > 0:
        print('开始生成....:')
        yield n
        print('完成一次...')
        n -= 1


if __name__ == '__main__':


    my_yield = myYield(3)
    print('已经实例化生成器对象')
    my_yield.__next__()
    print('第二次调用__next__()方法:')
    my_yield.__next__()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述
答案跟定义相同!!!

深入生成器

yield语句不仅可以使函数成为生成器和返回值,还可以接受调用者传来的数值。但值得注意的是:第一次调用生成器时不能传送给生成器None以外的值,否则会引发错误。

例子:实现递减生成器,避免传入None以外的值

def myYield(n):
    while n > 0 :
        rcv = yield n
        n -= 1
        if rcv is not None:
            n = rcv

if __name__ == '__main__':
    my_yield = myYield(3)
    print(my_yield.__next__())
    print(my_yield.__next__())

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

生成器与协程

采用一般的方法来实现生产者与消费者这个传统的并发与同步程序设计问题,通过生成器实现

例子:生产者模型

def consumer():
    print('等待接受处理任务....')
    while True:
        data = (yield)
        print('收到任务:', data)


def producer():
    c = consumer()
    c.__next__()
    for i in range(3):
        print('发送一个任务....', '任务%d' % i)
        c.send('任务%d' % i)


if __name__ == '__main__':
    producer()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

装饰器

装饰器是一种增加函数或类功能的简单方法,它可以快速地给不同的函数或类插入相同的功能。

装饰器概述

要用装饰器来装饰对象,必须先定义装饰器,装饰器的定义与普通函数的定义在形式上完全一致,只不过装饰器函数的参数必须有函数或类对象,然后在装饰器函数中重新定义一个新的函数或类,并在其中执行某些功能前后或中间来使用被装饰的函数或类,最后返回这个新定义的函数或类。

装饰函数

用装饰器装饰函数,首先要定义装饰器,然后用定义的装饰器来装饰函数

例子:自定义一个装饰器,使其函数运行开始时有提示,结束时也有提示

def abc(fun):
    def wrapper(*args, **kwargs):
        print('开始运行...')
        fun(*args, **kwargs)
        print('运行结束!')

    return wrapper


@abc
def demo_decoration(x):
    a = []
    for i in range(x):
        a.append(i)
    print(a)




if __name__ == '__main__':
    demo_decoration(5)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述

装饰类

装饰器不仅可以装饰函数,也可以装饰类。定义装饰类的装饰器,采用的方法是:定义内嵌类的函数,并返回新类。

例子:演示一个装饰类实现打印三个坐标值

def abc(myclass): # 定义类装饰器
    class InnerClass: # 定义内嵌类
        def __init__(self,z=0):


    

            self.z = 0
            self.wrapper = myclass() # 实例化被装饰类

        def position(self):
            self.wrapper.position()
            print('z axis:', self.z)


    return InnerClass

@abc
class coordination(object):
    def __init__(self,x=0,y=0):
        self.x = x
        self.y = y

    def position(self):
        print('x axis:',self.x)
        print('y axis:',self.y)

if __name__ == '__main__':
    coor = coordination()
    coor.position()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在这里插入图片描述

总结

通过迭代器、生成器、装饰器的学习,python的内化功夫又上升了一个档次。其中迭代器可以不断地遍历,生成器一次生成一个,装饰器简化函数操作。都是及其有用的

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/70714
 
179 次点击