1、迭代器
迭代器是Python提供的用于访问集合
,是一种可以记住遍历位置的对象
,会从第一个元素开始访问,直到结束。可以通过内置的iter()函数
来获
对应的迭代器对象
,然后直接循环遍历这个迭代器对象;或者通过另外一个内置的next()函数
,返回容器的下一个元素
,不过如果超过结尾会报StopIteration异常
,使用代码示例如下:
import sys a = [1, 2, 3, 4, 5] it1 = iter(a) # 直接遍历迭代器对象 for x in it1: print(x, end='\t') else: print() # 每调用一次next向后访问一个元素,超过元素会报StopIteration异常 it2 = iter(a) print(next(it2), end='\t') print(next(it2), end='\t') print(next(it2), end='\t') print(next(it2), end='\t') print(next(it2), end='\t') print() # 带异常捕获方法 it3 = iter(a) while True: try: print(next(it3), end='\t') except StopIteration: sys.exit()
运行结果如下:
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
另外有一点要进行区分:iterable
和 iterator
,前者只实现了iter函数
,而后者同时实现了iter和next函数
。比如List只是一个iterable而不是iterator,所以只支持iter(),不支持next(),需要调用iter()函数获得一个iterator对象。如果调用下type(it1),会发现数据类型是:<class 'list_iterator'>
,这是Python为list提供的默认迭代器对象。我们也可以自己来实现一个iterator,代码示例如下:
class MyIterator(): def __init__(self, names): self.names = names self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.names): raise StopIteration("已到达末尾") else: self.index += 1 return self.names[self.index - 1] iterator = MyIterator([1, 2, 3, 4, 5]) for i in iterator: print(i, end='\t')
运行结果如下:
1 2 3 4 5
2、生成器
叫「生成器函数」会更贴切一些,一种特别的函数,用yield关键字
来返回一个生成器对象,本质上还是迭代器,只是更加简洁,yield对应的值在函数调用时候不会立即返回,只有去调用next()函数
的时候才会返回,而使用for xxx in xxx的时候其实调用的还是next()函数
,最简单的生成器代码示例如下:
def func(n): yield n * n if __name__ == '__main__': print(func(10)) print(next(func(10))) for i in func(10): print(i)
运行结果如下:
<generator object func at 0x0000015D06436308> 100 100
可以看到返回的对象类型是generator
,相比起迭代器,生成器显得更加优雅简洁,比如最经典的实现斐波那契数列的例子:
def func(n): a, b = 0, 1 while n > 0: n -= 1 yield b a, b = b, a + b for i in func(10): print(i, end="\t")
运行结果如下:
1 1 2 3 5 8 13 21 34 55
3、装饰器
本质上也是「函数」,作用是:帮助其他函数在不改动代码的情况下增加额外的功能,装饰器函数的返回值也是一个函数。
① 一步步了解装饰器
装饰器对于很多初学者来说有点难以理解,举个简单的奶茶例子慢慢引入吧(因为手边刚好有一杯一点点奶茶,另外函数名不要用中文,这里用中文只是想让读者更容易理解,还有命名习惯:类名驼峰命名,函数名下划线分割命名!)
import time def 波霸奶茶(): time.sleep(1) print("制作一杯波霸奶茶") if __name__ == '__main__': 波霸奶茶()
运行结果如下:
制作一杯波霸奶茶
现在笔者想知道制作一杯波霸奶茶花费的时间,可以改动下波霸奶茶这个函数:
def 波霸奶茶(): start = time.clock() time.sleep(1) print("制作一杯波霸奶茶") end = time.clock() print("耗时", end - start) if __name__ == '__main__': 波霸奶茶()