python高阶版之生成器&装饰器

最近在给同事组织培训,提到了python的高阶使用。下述代码都是培训实例,相对于比较简单易理解的方式让大家理解,不妨上手一试试~

本质:都是函数,区别在于实现的功能不同


1、生成器


先考虑两个场景:
1、读取一个10几G大的文件txt,直接打开读取则造成内存消耗过高,cpu升,系统卡
2、我们创建一个列表,但受到内存限制,列表容量有限。而且访问一个具有100万数据列表的某几个元素,那绝大多数元素占用的空间都浪费
生成器函数应运而生~
生成器函数之列表推导式超进化~~~

# 列表推导式演变进化来的生成器函数
def generate_list_simple():
    # 假设列表容纳了100万个数字,占用内存极大
    list1 = [1,2,3,4,5,6,7,100, 101]
    aa = (a for a in range(len(list1)))

    # print(aa, type(aa))
    # print(aa.__next__())    # aa.__next__() 或  next(aa)
    # print(aa.__next__())
    # print(aa.__next__())    # 通过控制台输出,发现每次都是从上一个元素结束的位置开始
    # print(aa.__next__())    # 通过控制台输出,发现每次都是从上一个元素结束的位置开始
    # print(aa.__next__())    # 通过控制台输出,发现每次都是从上一个元素结束的位置开始

    # 上述表达太累赘,多行print,有别的办法吗?


    # 一步到位,1、节约空间 2、需要的元素位置未知 降低大数据量读cpu的能耗
    for i in aa:    # 循环的对象是个生成器,并不会像列表对象一样全部读取进来,而是一个个读取生成器
        print('for循环打印输出i》》{}'.format(i))
        if i == 3:
            i *= 2
            print('for循环打印输出计算后的i值:{}'.format(i))
            break


generate_list_simple()

生成器概念:包含yield的函数就是生成器函数。(yield可以理解成:返回中间变量但不退出函数的return效果)。生成器可以暂时挂起函数,保留中途数据,每次调用的位置是上一次暂停的位置。通俗说就是一边循环一边计算的机制就叫生成器。

# 生成器函数:函数体带yield的函数
def gene_yield(n):
    while n > 0:
        print('-----yield前--------')
        # 凡是遇到yield的,暂停
        yield n
        print('yield语句之后打印输出——>>{}'.format(n))
        print('-----yield后--------')
        n -= 1
# 实例化函数
g = gene_yield(10)



# # 方法1 next()方式输出
# next(g)



# 方法2 next()方式输出  n=1000000,999
for i in g:     # g是生成器对象
    m = next(g)
    print('方法2打印的m的值-->{}'.format(m))
    if m == 7:
        m *= m  # 计算可根据业务需要来定
        print('取到某个中间值时,输出计算后的m:{}'.format(m))
        break

**

2、装饰器

**
为了装饰其他函数而存在的一类函数。分为不带参数的函数装饰器和带参数的函数装饰器。装饰器函数的参数为被调函数的函数名(注意是函数名,不是函数实例化对象)。

装饰器用途:
1、处理被装饰的函数并返回
2、被装饰函数替换成另一个函数
使用方法:
将 @装饰器名 放在被装饰对象的上面

# 利用函数装饰器计算 被调函数执行 时长
import time

# 带参数的函数装饰器
def timecount(func):    # 参数func为被装饰函数的函数名
    def wrapper(*args, **kwargs):   # 通过可变位置参数、可变关键字参数可自适应接收任意参数
        print(args, kwargs)  # 打印被装饰函数的参数
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print(func.__name__, end - start)
    return wrapper  # 函数timecount 返回 wrapper对象

# 被装饰的函数--带参数
@timecount
def autodown(n: int):
    while n > 0:
        n -= 1
# 调用被装饰的函数
autodown(100000)
autodown(1000000)
autodown(10000000)

# # 被装饰的函数--无参数
# @timecount
# def autodown():
#     n = 10000
#     while n > 0:
#         n -= 1
# # 调用被装饰的函数
# autodown()
# autodown()
# autodown()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值