程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2021-12(24)

2022-01(11)

迭代器、生成器、装饰器

发布于2019-08-20 10:45     阅读(365)     评论(0)     点赞(28)     收藏(5)


迭代器

拥有__iter__方法和__next__方法的对象就是迭代器

dir()方法获取对应数据类型的所有方法

dir()方法获取对应数据类型的所有方法,带有下划线的方法叫双下方法。

例如:print(dir( [ ]))

找到__iter__方法,有此方法的对象就是一个可以被迭代的对象。

__iter__方法的作用是返回一个迭代器

一个列表执行了__iter__()方法后返回值就是一个迭代器。

  1. print([1,2,3].__iter__())
  2. #<list_iterator object at 0x0000000002124400>

 __iter__( )中 有一个__nexr__( )方法。这个方法可以迭代。

  1. k=[1,2,3]
  2. d=k.__iter__() #获取迭代器
  3. print(d.__next__()) #获取1元素
  4. print(d.__next__()) #2
  5. print(d.__next__()) #3

(二)for循环原理

1.for循环一个可迭代的对象(实现__iter__方法)

2.__iter__方法返回一个迭代器(迭代器实现了__iter__方法和__next__方法)

3.for先判断对象方可迭代,然后调用迭代器的__next__方法获取值。

(三)迭代器的作用

节约内存,取值的时候再生成数据。

生成器

生成器的本质就是迭代器

生成器包括两种:生成器函数和生成器表达式

(一)生成器函数

一个包含yield关键字的函数就是一个生成器函数。并且yield不能和return共用,并且yield只能用在函数内。

1.生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体。

2.执行了__next__( )方法之后才会执行函数体,并且获得返回值。

3.  .next() 内置方法,内部调用生成器函数的__next__()方法。

4. .yield和return相同的是可以返回值,但不同的是yield不会结束函数。

  1. def shengcheng(n):
  2. i=1
  3. while i<=n:
  4. yield i #yield返回值,并不会完全结束函数,而是保存下来当前的状态,
  5. #等到下次进入的时候,继续使用
  6. i+=1
  7. x=shengcheng(5)
  8. print(x)
  9. for y in x:
  10. print(y)

 

  1. def dee():
  2. yield 1
  3. yield 2
  4. yield 3
  5. x=dee()
  6. print(next(x))
  7. print(next(x))
  8. print(next(x))

(二)send()

send获取下一个值得效果和next()基本一致,只是在获取下一个值的时候,给上一个yield的位置传递一个数据

注意事项:

1第一次使用生成器时,是用next获取下一个值

2.最后一个yield不能接受外部的值。

  1. def g():
  2. print('a')
  3. x=yield 10
  4. print('接收数据',x)
  5. yield x+5
  6. x=g()
  7. print(next(x))
  8. b=x.send(999)
  9. print(b)
  10. #a
  11. #10
  12. #接收数据 999
  13. #1004

例题计算移动平均值:

(三)yield  form

yield from循环遍历容器类型

方式一:

  1. def g():
  2. yield from 'AB'
  3. yield from range(5)
  4. for x in g():
  5. print(x)
  6. #A b 0 1 2 3 4

方式二:

  1. def g():
  2. for x in 'AB':
  3. yield x
  4. for x in range(3):
  5. yield x
  6. for i in g():
  7. print(i)
  8. # A B 0 1 2

( 四)生成器表达式

格式:将列表解析式[ ]改成()即可

  1. b=(i for i in range(5))#生成器表达式
  2. print(b)
  3. #<generator object <genexpr> at 0x00000000027545E8>
  1. a=('鸡蛋%d'%i for i in range(1,6))
  2. print(next(a)) #鸡蛋1
  3. print(a.__next__()) #鸡蛋2
  4. print(list(a)) #['鸡蛋3', '鸡蛋4', '鸡蛋5']

 

装饰器

闭包

在python中创建一个闭包有三个要求

1.闭包函数必须有内嵌函数。

2.内嵌函数必须要引用外层函数变量。

3.闭包函数返回内嵌函数的地址(函数名称)

  1. def waiceng(b):
  2. a=3
  3. def neiceng(x):
  4. return x*a+b
  5. return neiceng
  6. x=waiceng(9)
  7. print(x(5))
  8. print(x(7))

判断闭报的函数的方法__closure__

输出的__closure__有 cell 元素  是闭包函数

输出的__closure__为None  不是闭包函数

  1. def waiceng():
  2. b=9
  3. def neiceng():
  4. print('哈哈',b)
  5. print(neiceng.__closure__)
  6. return neiceng
  7. x=waiceng()
  8. x()
  9. #(<cell at 0x0000000002771768: int object at 0x000007FED5FE6390>,)
  10. #哈哈 9

装饰器

装饰器的本质:一个闭包函数

作用:在不修改原函数及其调用方式的情况下对原函数功能进行扩展。

  1. import time
  2. def decor(f):
  3. def neibu():
  4. #被装饰的函数之前执行的代码
  5. t=time.time()
  6. f() #被装饰的函数
  7. #被装饰的函数之后执行的代码
  8. t2=time.time()
  9. print('时间{}'.format(t2-t))
  10. return neibu
  11. @decor
  12. def func2():
  13. s=0
  14. for i in range(12771):
  15. s+=1
  16. print(s)
  17. func2()
  18. #12771
  19. #时间0.0009999275207519531

(三)@property装饰器

1.@property内置装饰器函数,把每一个方法调用方式变成属性调用方式。(将一个方法当成属性使用)。@property装饰器只能在面向对象中使用。

2.访问使用@property装饰器装饰的函数可以直接调用函数名。(会执行一段功能(函数),然后返回值)

3.@property装饰器只能修饰不带参数的方法。

  1. class A():
  2. def __init__(self,name):
  3. self.__name=name
  4. @property
  5. def name(self):
  6. return self.name
  7. # @name.setter #没有设置setter装饰器,不能设置name属性的值。
  8. def name(self,x):
  9. self.__name=x
  10. a=A('张三')
  11. print('张三')
  12. a.name='李四'
  13. print
  14. #张三

 

 



所属网站分类: 技术文章 > 博客

作者:站起来

链接:https://www.pythonheidong.com/blog/article/49002/7b187375344fba4770a0/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

28 0
收藏该文
已收藏

评论内容:(最多支持255个字符)