迭代器、生成器、装饰器

迭代器

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

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

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

例如:print(dir( [ ]))

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

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

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

print([1,2,3].__iter__())

#<list_iterator object at 0x0000000002124400>

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

k=[1,2,3]
d=k.__iter__()       #获取迭代器
print(d.__next__())  #获取1元素
print(d.__next__())  #2
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不会结束函数。

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

 

def dee():
    yield  1
    yield  2
    yield  3
x=dee()
print(next(x))
print(next(x))
print(next(x))

(二)send()

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

注意事项:

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

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

def g():
    print('a')
    x=yield 10
    print('接收数据',x)
    yield x+5
x=g()
print(next(x))
b=x.send(999)
print(b)

#a
#10
#接收数据 999
#1004

例题计算移动平均值:

(三)yield  form

yield from循环遍历容器类型

方式一:

def g():
    yield from 'AB'
    yield from range(5)
for x in g():
    print(x)

#A b 0 1 2 3 4 

方式二:

def g():
    for x in 'AB':
        yield x

    for x in range(3):
        yield x
for i in g():
    print(i)

# A B 0 1 2

( 四)生成器表达式

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

b=(i for i in range(5))#生成器表达式
print(b)

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

 

装饰器

闭包

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

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

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

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

def waiceng(b):
    a=3
    def neiceng(x):
        return x*a+b
    return neiceng
x=waiceng(9)
print(x(5))
print(x(7))

判断闭报的函数的方法__closure__

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

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

def waiceng():
    b=9
    def neiceng():
        print('哈哈',b)
    print(neiceng.__closure__)
    return neiceng
x=waiceng()
x()

#(<cell at 0x0000000002771768: int object at 0x000007FED5FE6390>,)
#哈哈 9

装饰器

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

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

import time
def decor(f):
    def neibu():
        #被装饰的函数之前执行的代码
        t=time.time()
        f()        #被装饰的函数
        #被装饰的函数之后执行的代码
        t2=time.time()
        print('时间{}'.format(t2-t))
    return neibu
@decor
def func2():
    s=0
    for i in range(12771):
        s+=1
    print(s)
func2()

#12771
#时间0.0009999275207519531

(三)@property装饰器

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

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

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

class A():
    def __init__(self,name):
        self.__name=name
    @property
    def name(self):
        return self.name
    # @name.setter #没有设置setter装饰器,不能设置name属性的值。
    def name(self,x):
      self.__name=x
a=A('张三')
print('张三')
a.name='李四'
print

#张三

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值