[python自学笔记]生成器、迭代器、装饰器
2018-02-01 14:43
501 查看
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator通过列表生成式的方式创建生成器
#可以通过列表生成式创建生成器,只需要把[]换成()即可 In [1]: a = [x for x in range(10) ] In [2]: a Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [3]: a = (x for x in range(10)) In [4]: a Out[4]: <generator object <genexpr> at 0x7ffa50d98e08> #生成器可以通过 next() 函数获得生成器的下一个返回值 In [5]: next(a) Out[5]: 0 In [6]: next(a) Out[6]: 1 In [7]: next(a) Out[7]: 2 In [8]: next(a) Out[8]: 3 In [9]: next(a) Out[9]: 4 #此外,生成器可以用for循环遍历 In [12]: a = [x for x in range(10) ] In [13]: a Out[13]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] In [14]: for i in a: ....: print(i) ....: 0 1 2 3 4 5 6 7 8 9
通过含yield函数的方式创建生成器
In [30]: def fib(times): ....: n = 0 ....: a,b = 0,1 ....: while n<times: ....: yield b ....: a,b = b,a+b ....: n+=1 ....: return 'done' ....: In [31]: F = fib(5) In [32]: next(F) Out[32]: 1 In [33]: next(F) Out[33]: 1 In [34]: next(F) Out[34]: 2 In [35]: next(F) Out[35]: 3 In [36]: next(F) Out[36]: 5 In [37]: next(F) --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-37-8c2b02b4361a> in <module>() ----> 1 next(F) StopIteration: done In [38]: for n in fib(5): ....: print(n) ....: 1 1 2 3 5 In [39]:
迭代器
1. 可迭代对象以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
一类是 generator ,包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。
2. 判断是否可以迭代
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:
In [50]: from collections import Iterable In [51]: isinstance([], Iterable) Out[51]: True In [52]: isinstance({}, Iterable) Out[52]: True In [53]: isinstance('abc', Iterable) Out[53]: True In [54]: isinstance((x for x in range(10)), Iterable) Out[54]: True In [55]: isinstance(100, Iterable) Out[55]: False
而生成器不但可以作用于 for 循环,还可以被 next() 函数不断调用并返回下一个值,直到最后抛出 StopIteration 错误表示无法继续返回下一个值了。
3.迭代器
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用 isinstance() 判断一个对象是否是 Iterator 对象:
In [56]: from collections import Iterator In [57]: isinstance((x for x in range(10)), Iterator) Out[57]: True In [58]: isinstance([], Iterator) Out[58]: False In [59]: isinstance({}, Iterator) Out[59]: False In [60]: isinstance('abc', Iterator) Out[60]: False In [61]: isinstance(100, Iterator) Out[61]: False
4.iter()函数
生成器都是 Iterator 对象,但 list 、 dict 、 str 虽然是 Iterable ,却不是 Iterator 。把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数:
In [62]: isinstance(iter([]), Iterator) Out[62]: True In [63]: isinstance(iter('abc'), Iterator) Out[63]: True
凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型
集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter()函数获得一个 Iterator 对象。
装饰器
1.闭包就是函数里面定义一个函数,并返回,返回值是一个函数,类似于C++里面的函数指针的意思。
#定义一个函数 def test(number): #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包 def test_in(number_in): print("in test_in 函数, number_in is %d"%number_in) return number+number_in #其实这里返回的就是闭包的结果 return test_in #给test函数赋值,这个20就是给参数number ret = test(20) #注意这里的100其实给参数number_in print(ret(100)) #注意这里的200其实给参数number_in print(ret(200))
运行结果:
in test_in 函数, number_in is 100 120 in test_in 函数, number_in is 200 220
2. 函数
函数名也是个对象,是指向函数体的一个指针,当然也可以指向别的地方
In [1]: def foo(): ...: print("foo") ...: In [2]: foo Out[2]: <function __main__.foo> In [3]: foo() foo # 让foo指向别的函数 In [4]: foo = lambda x:x+1 In [5]: foo(5) Out[5]: 6
3. 装饰器
一个函数功能不够强大,在不修改原来函数的基础上增加新的功能,同装饰模式。
def w1(func): print("this is w1") def inner(): print("this is an added function") func() return inner @w1 def f1(): print('this is original function') f1()
执行结果:
this is w1 this is an added function this is original function
执行过程
@w1的过程就是 f1 = w1(f1)的过程,所以会执行w1函数,但w1内部是定义inner函数,并没有执行,等到执行f1函数的时候,f1指向了inner函数,而func指向了原来的f1函数,因此得到了上面的结果
在比如说:
#定义函数:完成包裹数据 def makeBold(fn): def wrapped(): return "<b>" + fn() + "</b>" return wrapped #定义函数:完成包裹数据 def makeItalic(fn): def wrapped(): return "<i>" + fn() + "</i>" return wrapped @makeBold def test1(): return "hello world-1" @makeItalic def test2(): return "hello world-2" @makeBold @makeItalic def test3(): return "hello world-3" print(test1())) print(test2())) print(test3()))
执行结果:
<b>hello world-1</b> <i>hello world-2</i> <b><i>hello world-3</i></b>
执行过程:
仅说明test3,test3函数先被makeItalic函数装饰,再被makeBold装饰,首先第一步,test3被makeItalic函数装饰后,test3指向了makeItalic里面的wrapped函数,也就是返回值为hello world-3,makeItalic的fn指向了原来的test3函数,也就是return “hello world-3”那个,随后再被makeBold函数装饰,那么test3指向了makeBold里面的wrapped函数,makeBold里面的fn指向了上一步test3指向的那个函数。所以执行test3便是执行makeBold函数里面的wrapped函数,只不过是makeBold里面的fn指向了已经被makeItalic装饰过的test
装饰器例子:
from time import ctime, sleep def timefun(func): def wrappedfunc(a, b): print("%s called at %s"%(func.__name__, ctime())) print(a, b) func(a, b) return wrappedfunc @timefun def foo(a, b): print(a+b) foo(3,5) sleep(2) foo(2,4)
from time import ctime, sleep def timefun(func): def wrappedfunc(*args, **kwargs): print("%s called at %s"%(func.__name__, ctime())) func(*args, **kwargs) return wrappedfunc @timefun def foo(a, b, c): print(a+b+c) foo(3,5,7) sleep(2) foo(2,4,9)
from time import ctime, sleep def timefun(func): def wrappedfunc(): print("%s called at %s"%(func.__name__, ctime())) func() return wrappedfunc @timefun def foo(): print("I am foo") @timefun def getInfo(): return '----hahah---' foo() sleep(2) foo() print(getInfo())
执行结果:
foo called at Fri Nov 4 21:55:35 2016 I am foo foo called at Fri Nov 4 21:55:37 2016 I am foo getInfo called at Fri Nov 4 21:55:37 2016 None
相关文章推荐
- python学习笔记四 迭代器,生成器,装饰器(基础篇)
- python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化
- Python3学习笔记:迭代器与生成器
- python学习笔记9-迭代器和生成器整理
- python 学习2:生成器,迭代器,装饰器
- python cookbook第三版学习笔记六:迭代器与生成器
- python 学习2:生成器,迭代器,装饰器
- python的迭代器、生成器、装饰器
- PYTHON自学笔记4之列表生成器
- Python学习笔记——迭代器和生成器
- 我的Python3.0笔记之容器,迭代器,生成器
- python学习笔记之八:迭代器和生成器
- python学习笔记-生成器,迭代器,协程定义
- 流畅python学习笔记:第十四章:迭代器和生成器
- Python笔记(3)迭代器与生成器
- python学习-Day15-python生成式和生成器、迭代器、装饰器
- Python 学习笔记 迭代器和生成器
- 循序渐进Python3(四) -- 装饰器、迭代器和生成器
- Python高级特性(切片 迭代 列表生成式 生成器 迭代器)学习笔记
- 装饰器、生成器、迭代器、及python中内置函数的使用