【十】迭代器、生成器、装饰器和标准库

一:迭代器

在python中,很多对象可以直接通过for语句来直接遍历,例如:list、string、dict等等,这些被称为可迭代对象

迭代器是一个可以I记住遍历的位置的对象。

在python中,支持迭代器协议的就是实现对象的iter()和next()方法。

  • iter()方法返回迭代器本身
  • next()方法返回容器的下一个元素
  • 在结尾时引发stopiteration异常

迭代器有两个基本的方法:__iter__()和next()方法,一个用来获取迭代器对象,一个用来获取容器中的下一个元素

In [1]: l=[1,2,3,4,54]
In [2]: it=iter(l)
#通过iter()方法获得了list的迭代对象
In [3]: it
Out[3]: <list_iterator at 0x7f4242c89e10>
#通过next方法获取下一个元素
In [4]: next(it)
Out[4]: 1
In [5]: next(it)
Out[5]: 2
In [6]: next(it)
Out[6]: 3
In [7]: next(it)
Out[7]: 4
In [8]: next(it)
Out[8]: 54
#当容器中没有可访问的元素后,抛出stopiteration异常
In [9]: next(it)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-9-2cdb14c0d4d6> in <module>()
----> 1 next(it)

StopIteration: 

其实,当我们使用for语句的时候,for语句会自动通过iter()方法来获得迭代对象,并通过next()方法获取下一个元素

二:生成器

生成器是用来创建python序列的一个对象,使用它可以迭代庞大的序列,且不需要在内存中创建和储存整个序列

#range生成器
In [10]: sum(range(1,101))
Out[10]: 5050

每次迭代生成器,它都会记录上一次调用的位置,并且返回下一个值

生成器函数和普通函数类似,但是他的返回值使用yield语句声明,而不是return

生成器是为迭代器产生数据的。

In [14]: def my_range(first=0,last=10,step=1):
    ...:     number=first
    ...:     while number<last:
    ...:         yield number
    ...:         number+=step
    ...:
#这是一个普通的函数
>>> my_range
<function my_range at 0x1070c4e18>
#返回的是一个生成器对象
In [15]: my_range()
Out[15]: <generator object my_range at 0x7f4241b83fc0>
#对这个生成器对象进行迭代
In [16]: ranger=my_range(1,5)
In [17]: for i in ranger:
    ...:     print(i)
    ...:
1
2
3
4
In [18]: print(ranger)
<generator object my_range at 0x7f424291ea40>
#在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。
In [19]: list(ranger)
Out[19]: []#因为yield是记住位置的,ranger只里面的内容在for迭代已经全部取出来了,所以这里面为空
In [20]: ranger=my_range(1,5)
#还没有进行迭代,所以数据都还存在
In [21]: list(ranger)
Out[21]: [1, 2, 3, 4]

习题:使用生成器写一个斐波纳挈数列

In [24]: def shulie():
    ...:     num=int(input("请输入一个整数"))
    ...:     f1=0
    ...:     f2=1
    ...:     if num<=0:
    ...:         print("请输入一个正整数")
    ...:     elif num==1:
    ...:         print("斐波纳挈数列:%d"%f1)
    ...:     else:
    ...:         print("斐波纳挈:",end="")
    ...:         for n in range(1,num-1):
    ...:             f=f1+f2
    ...:             f1,f2=f2,f
    ...:             print(f,end="")
    ...:             

In [25]: shulie()
请输入一个整数0
请输入一个正整数

In [26]: shulie()
请输入一个整数1
斐波纳挈数列:0
#输出前10项的斐波纳挈数列
In [29]: shulie()
请输入一个整数10
斐波纳挈:12358132134

三:装饰器

1.args和*kwargs

In [46]: def x(*args,**kwargs):
    ...:     print(args) #输出参数的时候不需要加*
    ...:     print(kwargs)
    ...:
#从如下例子可以看出,*args就是一个列表,**kwargs就是一个字典
In [47]: x(1,2,3)
(1, 2, 3)
{}
In [49]: x(1,2,3,one=1,two=2)
(1, 2, 3)
{‘two‘: 2, ‘one‘: 1}
In [50]: x(one=1,two=2)
()
{‘two‘: 2, ‘one‘: 1}

2.闭包

In [51]: def foo(x,y):
#x,y为自由变量
    ...:     def bar():
    ...:         a=4
    ...:         return x+y+a
    ...:     return bar
    ...:
In [52]: bar=foo(1,2)
In [53]: bar
Out[53]: <function __main__.foo.<locals>.bar>
In [54]: bar()
Out[54]: 7

3.作为参数的函数

函数document_it()定义了一个装饰器,需实现如下功能:

  • 打印输出函数的名字和参数值
  • 执行含有参数的函数
  • 打印输出结果
  • 返回修改后的函数
#装饰器
In [75]: def documenyt_it(func):
    ...:     def new_func(*args,**kwargs):
    ...:         print("func name",func.__name__)
    ...:         print("args",args)
    ...:         print("kwargs",kwargs)
    ...:         result=func(*args,**kwargs)
    ...:         print("result",result)
    ...:         return result
    ...:     return new_func
    ...: 

In [76]: def add(a,b):
    ...:     return a+b
    ...: 

In [77]: add(3,5)
Out[77]: 8

In [78]: test_add=documenyt_it(add) #人工对装饰器赋值

In [79]: test_add(3,5)
func name add
args (3, 5)
kwargs {}
result 8
Out[79]: 8

#自己设定装饰器

#coding=utf-8
def document_it(func):
    def new_func(*args,**kwargs):
        print(‘func name‘,func.__name__)
        print(‘args‘,args)
        print(‘keyword args‘,kwargs)
        result=func(*args,**kwargs)
        print(‘result‘,result)
        return result
    return new_func
def square_it(func):
    def new_function(*args,**kwargs):
        result=func(*args,**kwargs)
        return result*result
    return new_function
@square_it  #装饰器
@document_it
def add(a,b):
    return a+b
#注意:打印结果:函数越靠近哪个装饰器就执行那个装饰器内的数据
print(add(3,5))
#add=add(sqare_it(document_it(add)))

打印结果:

C:\Python27\python.exe "D:/PyCharm Community Edition 5.0.3/代码/ex89.py"
(‘func name‘, ‘add‘)
(‘args‘, (3, 5))
(‘keyword args‘, {})
(‘result‘, 8)
64

Process finished with exit code 0
时间: 2024-10-05 11:19:33

【十】迭代器、生成器、装饰器和标准库的相关文章

Python 迭代器&amp;生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

迭代器,生成器,装饰器,递归

迭代器 可迭代对象 1)定义:在python中,但凡内部含有--itter--方法的对象,都是可迭代对象 可以通过dir()去判断一个对象具有什么方法 dir()会返回一个列表,这个列表中含有该对象的以字符串形式的所有方法 从字面意思来说:可迭代对象就是一个可以重复取值的数据集. 从专业角度来说:但凡内部含有iter方法的对象,都是可迭代对象 . 可迭代对象可以通过判断该对象是否有’iter’方法来判断. 可迭代对象的优点: 可以直观的查看里面的数据.操作方法多,灵活 可迭代对象的缺点: 1.占

python 迭代器 生成器 装饰器

迭代器 可以直接作用于for循环的对象统称为可迭代对象(Iterable). 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator). 所有的Iterable均可以通过内置函数iter()来转变为Iterator. names = iter(['sun', 'ibm', 'sunny']) print(names) print(names.__next__()) print(names.__next__()) print(names.__next__()) print(

python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: 1 >>> g = (x * x for xin range(10)) 2 >>> g3 <generator object <genexpr> at 0x1022ef630> 此处g就是一个生成器. 迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是gene

python 装饰器及标准库functools中的wraps

最近在看 flask的视图装饰器 时,忽然想起预(复)习一下python的装饰器. 这里有一篇比较好的讲解装饰器的书写的 Python装饰器学习(九步入门) . 这里不单独记录装饰器的书写格式了,重点是工作流程. 首先常见的 装饰器 格式就是通过@语法糖,简便的写法,让流程有些不太清楚. 装饰器不带参数的情况下: def deco(func):     def _deco():         print("before myfunc() called.")         func(

迭代器/生成器/装饰器

迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和next()方法.其中__iter__()方法返回迭代器对象本身:next()方法返回容器的下一个元素,在结尾时引发StopIteration异常 可迭代对象 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration),默认的list.tuple.stri.dict对象都是可以迭代的. isinstance(obj

Python 全栈开发五 迭代器 生成器 装饰器

一.迭代器 迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 迭代器有两个基本的方法:iter() 和 next(). 字符串,列表或元组对象都可用于创建迭代器,生成迭代器的方法是iter(): >>li = [1,2,3,4,5] >>it = iter(li) #生成一个迭代器 >>it.__next__() 1 >>next(it) #以上两种next都可以使用 2 >

Day4 - Python基础4 迭代器、装饰器、软件开发规范

Python之路,Day4 - Python基础4 (new版) 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1,你怎么实现?你可能会想到2种方式 >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>

Python_Day5_迭代器、装饰器、软件开发规范

本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 1.列表生成式,迭代器&生成器 列表生成 >>> a = [i+1 for i in range(10)] >>> a [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访