码迷,mamicode.com
首页 > 编程语言 > 详细

Python学习日记(5)简单了解迭代器、生成器、装饰器、上下文管理器

时间:2018-07-20 17:33:04      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:bsp   python   管理器   class   本质   迭代器   对象   结果   break   

迭代器

迭代器只不过是一个实现了迭代器协议的容器对象。它基于以下两个方法。

__ next __:返回容器的下一个元素。

__ iter __:返回迭代器本身。

实际上,迭代器表现了程序底层的概念和特性,在程序中,你可以不必使用迭代器,但是理解迭代器,却是对生成器这样一个常用特性理解很有帮助。

学习迭代器,我基本上通过2个例子来理解迭代器的特性。(PS:我发现我之前记得笔记不是很详细,所以这一篇记录详细一些……不然我有时候一些点我自己看的时候都要想一下,吐血,果然没什么灵性……)

好了,上代码:

a = iter([11,22,33])

print(next(a))
print(next(a))
print(next(a))

-------------------------
11
22
33
[Finished in 0.2s]

这里,我创建了一个非常简陋的迭代器,使用iter()函数,这个函数在上述的代码中接收了一个列表作为参数,并赋值给a这个变量。

那么此时,a就是一个迭代器了。当然,此时创建的这个a的迭代器非常的简陋,就好比我要造飞机,结果你用纸给我叠了一个。不过飞机的特性还是有的,可以算是飞机了,只不过是纸飞机。

迭代器使用:通过函数next()来使用,next()函数参数接收一个迭代器,并在每一次执行的时候,依次调取迭代器中的值,并返回出来。

简单理解:next()函数呢,就好比游戏登录器,游戏就好比迭代器,没有登录器你玩不了游戏,所以,没next()这玩意你用不了迭代器,想用迭代器,你需要用next()这个方法调,next()这个方法有一个特点,从头开始调,每次调一个。

那么,为什么说我们用iter()创建的迭代器是纸飞机呢?

看代码思考2个问题:

1,每次调用是进行依次调用的,上述代码调用的刚好是个列表,如果,调用列表中最后一个值之后,继续调用,会怎么样呢?

a = iter([11,22,33])

print(next(a))
print(next(a))
print(next(a))
print(next(a))

-------------------------
StopIteration
[Finished in 0.2s with exit code 1]

可以看到,迭代器中只有3个值,而我调用了4次,所以在第四次调用的时候,返回了一个StopIteration异常。这是好事,异常代表着迭代的完结,我们可以利用异常做点事情。

2,为什么说纸飞机呢,这个迭代器有一个非常不好的点,那就是迭代的次数并非我们想要的,如果我们想迭代100次,总不至于写一个有100个元素的列表吧?当然,你可以说我可以用range()来解决这个问题呀。

a = iter(range(4))

print(next(a))
print(next(a))
print(next(a))
print(next(a))
 
-------------------------------
0
1
2
3
[Finished in 0.2s]

可是,实际上,并没有解决触发异常的问题。并且每一次的迭代,都需要next()来手工进行,那么,我们来做一个真正的迭代器。

class CountDown():
    def __init__(self,step):
        self.step = step

    def __next__(self):
        if self.step <= 0:
            raise StopIteration
        self.step = self.step - 1
        return self.step

    def __iter__(self):
        return self

ff = CountDown(5)
for i in ff:
    print(i)

-------------------------------------
4
3
2
1
0
[Finished in 0.2s]

 

__ next __:返回容器的下一个元素。

__ iter __:返回迭代器本身。

这个类就非常明确了,接收迭代次数,并且每次迭代减1,触发异常停止迭代。实际上,迭代只是一种概念,迭代器则提供了一种专门的方法,并非在python程序中唯一的迭代动作!

生成器

生成器是一种优雅的方法,他可以让编写返回元素序列的函数代码变得简单,高效。

实际上,我们常用的方法:range()

for i in range(10):
    print(i)

也是生成了一个列表来供我们遍历,在python3中,本质也是生成器。

当然,我们也可以自己写一个列表生成器,不使用range()

def Maker(num):
    a = 0
    while True:
        b = a
        a = a + 1
        num =  num - 1
        yield b
        if num <= 0:
            break

ff = Maker(10)

a = [i for i in Maker(10)]
b = [x for x in range(10)]
print(a)
print(b)
--------------------------------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[Finished in 0.2s]

看,我们自己写了一个生成器方法Maker(),这个方法接收一个参数,来表示生成列表数量,与range()函数的方法是一样的。(起码在调用看来是的)

代码中的:yield语句,表示暂停生成器,返回结果。是不是有点像return?可以想一想,是有区别的,一个是暂停,返回后继续执行后面的代码,return返回后就不在执行啦。

实际上,生成器可以执行复杂的生成过程,不过具体还是要看你要实现什么需求。

 

Python学习日记(5)简单了解迭代器、生成器、装饰器、上下文管理器

标签:bsp   python   管理器   class   本质   迭代器   对象   结果   break   

原文地址:https://www.cnblogs.com/shsm/p/9342552.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!