迭代器、生成器、装饰器

迭代器

迭代器定义

  • 拥有 _ iter _方法和 _ next _ 方法的对象就是迭代器
  • 迭代
    • 迭代是访问集合元素的一种方式,可以将某个数据集内的数据‘一个挨着一个的取出来’,就叫做迭代。
  • 可迭代协议
    • 协议就是互相规定好的。可迭代协议的定义非常简单,就是内部实现了_ iter _方法和 _ next _ 方法。
  • 迭代器协议
    • 必须拥有_ iter _方法和 _ next _ 方法
  • 下面用迭代器生成一个斐波那契数列,代码示例如下:
class Fib():
    def __init__(self,num):
        self.num = num
        self.a = 1
        self.b = 1
        self.count = 1
    def __iter__(self):
        return self
    def __next__(self):
        if self.count <= self.num:
            temp = self.a
            self.a,self.b = self.b,self.a+self.b
            self.count+=1
            return temp
        else:
            raise StopIteration
print(Fib(10))
for x in Fib(10):
    print(x)
  • 迭代器作用
    • 节约内存,在取的时候再生成数据

生成器

  • 生成器的本质就是迭代器
  • 生成器包括两种:生成器函数和生成器表达式

生成器函数

  • 一个包含yield关键字的函数就是一个生成器函数,并且yield和return不能共用,并且yield只能用在函数内。
    • 生成器函数执行了之后会得到一个生成器作为返回值,并不会执行函数体。
    • 执行了 __ next __ ()方法之后才会执行函数体,并且获得返回值。
    • .next()内置方法,内部调用生成器函数的__ next __()方法。
    • .yield和return相同的是可以返回值,但不同的是yield不会结束函数
      示例代码如下:
def shengchan(n):
    i = 1
    while i <= n:
        yield i 
        i += 1
x = shengchan(5)
print(x)
for i in x:
    print(i)

输出结果如下:

<generator object shengchan at 0x0000000005347A40>
1
2
3
4
5

send()

  • send获取下一个值的效果和next()基本一致,只是在获取下一个值的时候,给上一个yield的位置传递一个数据
  • 使用send的注意事项
    • 第一次使用生成器的时候,是用next获取下一个值
    • 最后一个yield不能接受外部的值
      示例代码如下:
def g():
    count = 1
    get_num = 0
    avg = 0
    total = 0
    while True:
        get_num = yield avg
        total = total + get_num
        avg = total/count
        count+=1
x = g()
next(x)
print(x.send(10))
print(x.send(20))
print(x.send(30))

输出结果如下:

10.0
15.0
20.0

yield from

  • yield from循环遍历容器类型
    示例代码:
def g():
    yield from 'AB'
    yield from range(5)
for x in g():
    print(x)

输出结果如下:

A
B
0
1
2
3
4

生成器表达式

  • 格式:将列表解析式的 [ ]改成 ()即可。
    示例代码如下:
a = ('鸡蛋%d'%i for i in range(1,11))
print(a)
print(next(a))
print(a.__next__())
print(list(a))

输出结果如下:

<generator object <genexpr> at 0x0000000005966938>
鸡蛋1
鸡蛋2
['鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9', '鸡蛋10']

装饰器

闭包

  • 在python中创建一个闭包一般有3个要求:
    • 1.闭包函数必须有内嵌函数
    • 2.内嵌函数必须要引用外层函数的变量
    • 3.闭包函数返回内嵌函数的地址(函数名称)

装饰器

  • 装饰器函数的本质:一个闭包函数
  • 装饰器函数的作用:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
  • 语法糖:
    • 格式: @装饰器名称
      示例代码如下:
import time
def decor(f):
    def neibu():
        t1 = time.time()
        f()
        t2 = time.time()
        print('运行时间为:',(t2-t1))
    return neibu
@decor
def func():
    s = 1
    for i in range(1,9):
        s*=i
    print(s)
func()

检测程序运行时间,结果如下:

40320
运行时间为: 0.0010001659393310547

多个装饰器的话,会先执行离得近的装饰器

def zsq(f):
    def nb():
        print('************************')
        f()
        print('************************')
    return nb
def zsq2(f):
    def nb():
        print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
        f()
        print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
    return nb
@zsq2
@zsq
def f1():
    print('欢迎领导')
@zsq
def f2():
    print('好走,不送!')
f1()
print()
f2()

结果如下:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
************************
欢迎领导
************************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

************************
好走,不送!
************************

还可以创建带返回值的装饰器,示例如下:

def acor(f):
    def neibu(a,b):
        print('***********')
        d =f(a,b)
        print('***********')
        return d
    return neibu
@acor
def  func(a,b):
    c = a+b
    return c
print(func(2,3))

输出结果如下:

***********
***********
5
  • @property 装饰器
    • @property内置装饰器函数,把一个方法调用方式变成属性调用方式(将一个方法当成一个属性使用)。注意@property装饰器只能在面向对象中使用。
    • 访问使用@property装饰器装饰的函数可以直接调用函数名
    • @property装饰器只能修饰不带参数的方法
    • @property装饰器修饰私有方法的getter和setter方法。
      示例代码如下:
from math import pi
class Circle():
    def __init__(self,r):
        self.r = r
    @property
    def zhouchang(self):
        return self.r*2*pi
    @property
    def area(self):
        return pi*self.r**2
c = Circle(5)
print(c.zhouchang)
print(c.area)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值