python基础之装饰器、生成器、迭代器

一.装饰器:
定义:装饰器本质是函数,用来装饰其他函数(就是为其他函数添加附加功能)
原则:不能修改被装饰的函数的源代码及调用方式

实现装饰器知识贮备:
1.函数即‘变量’
2.高阶函数
a. 把一个函数名当作实参名转给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b.返回值中包含函数名(不修改函数的调用方式)
3.嵌套函数
a.在一个函数里用def定义一个新的函数才是函数嵌套

总结:
高阶函数+嵌套函数=>装饰器

示例:
def foo(func):  # 装饰器
def bar(*args): # 嵌套的函数
print('hello')
start_time=time.time()
ret=func(*args) # ret接收函数运行结果
end_time=time.time()
print('func run time:',end_time-start_time)
return ret # 返回函数运行的结果
return bar # 返回嵌套函数名

@foo # 相当于test1=foo(test1),为下面的函数添加附加功能
def test1(name,age): # 带参函数
time.sleep(3)
print('i am is test1 %s,age is %s' %(name,age))


@foo
def test2(): # 不带参数有返回值的函数
time.sleep(1)
print('i am is test2')
return '-----dan---------'

print(test2())
ret=test1('canshu',22)
print(ret)


二.生成器
     通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator,生成器保存的是算法,只能通过next()函数获得generator的下一个返回值
列表推导:
     list=[item for item in iterable]    # 元素一次性生成完,这样如果数量量大的话会占用大量内存空间
生成器:
只有在调用的时候才会生成相应的元素,只记录当前位置,只有一个方法__next__()(在2.0版本该方法名为next())
>>>g=(i for i in range(10000) )
>>>g.__next__()
>>> 0
>>>g.__next__()
>>> 1
yield   

def  fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b # 生成器
a, b = b, a + b
n = n + 1
return '---done---' # 发生异常的时候打印的消息

g=fib(6)
while True:
try:
x=next(g)
print('g"',x)
except StopIteration as e:
print('Generator return vale:',e.value)
break
    yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

三.迭代器


我们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如listtupledictsetstr等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象Iterable,可以使用isinstance()判断一个对象是否是Iterable对象.

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
判读下面对象是否是可迭代对象
print(isinstance('abc',Iterable))  # true
print(isinstance((),Iterable)) # true
print(isinstance([],Iterable)) # true
print(isinstance(123,Iterable)) # false
print(isinstance((x for x in range(10)),Iterable)) # true,判断生成器是否是可迭代对象
print(isinstance(iter([]),Iterator)) # iter()能把对象转换成迭代器,判断是否是迭代器
小结
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。


四.json模块
import json
# json模块的作用之一:根据字符串书写格式,将字符串自动转换成相应格式
inp_str='[11,22,33,44]'
inp_list=json.loads(inp_str) # 把字符串转换成列表
print(inp_list)
inp_dic=
'{"k1":22,"k2":"ee"}' # 把字符串字典(列表)转换成字典(列表),注意里面要用双引号,单引号报错
i_dic=json.loads(inp_dic)
print(i_dic)


posted @ 2016-12-08 17:21  远匿  阅读(140)  评论(0编辑  收藏  举报