Python的装饰器,推导式,生成器和迭代器

1.装饰器

遵循开放封闭原则,在不改变原函数的情况下,扩展了函数的功能 。

如果原函数有参数则装饰器内部函数也要有参数

原函数有返回值,则装饰器的内部函数也要有返回值

1.1装饰器的定义

格式:

#定义装饰器

def  aaa(func)    

       def ccc (参数,...)        

            ...        

            func()        

            ...        

            return yyy    

       return xxx

#装饰

@装饰器名

 1.2装饰器举例

#定义装饰器
def decorate(func):
    def wrapper():
        func()
        print('刷漆')
        print('铺地板')
        print('精装修房子')

    return wrapper


#装饰
@decorate
def house():
    print('毛坯房。。。')

#调用
house()

 输出结果

毛坯房。。。
刷漆
铺地板
精装修房子

1.3装饰器功能

1.引入日志

2.函数执行时间统计

3.执行函数前预备处理功能

4.执行函数后清理功能

5.权限校验等场景

6.缓存

2.推导式

2.1列表推导式

旧的列表———》新的列表

格式 : [表达式 for i变量 in 旧列表] 或者[表达式 for 变量 in 旧列表 if 条件]

例如:找出1-20之间的所有偶数

list1 = [i for i in range(1,21) if i%2==0]
print(list1)

输出结果为

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

2.2集合推导式

类似列表推导式,在列表推导式的基础上添加了一个去除重复项。

例如:

list1 = [1, 2, 3, 4, 5, 2, 7, 5, 4, 7, 4, 8, 5, 9, 6, 7]
set1 = {i for i in list1 if i > 5}
print(set1)

输出结果

 {8, 9, 6, 7}

2.3字典推导式

dict1 = {'a':'A','b':'B','c':'C','d':'C'}
new_dict = {value:key for key,value in dict1.items()}
print(new_dict)

输出结果

{'A': 'a', 'B': 'b', 'C': 'd'}

3.生成器

通过列表生成式(列表推导式),我们可以直接创建一个列表。

但是,受到内存限制,列表容量肯定是有限的。 而且创建一个包含100万个元素的列表,不仅占用很大的存储空间, 如果我们仅仅需要需要访问前面几个元素,那后面的绝大多数元素占用的空间就白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环过程中不断推算出后续的元素呢?

这样就不必创建完整的List,从而节省大量的空间,在python中,这种一边循环一边计算的机制,称为生成器:generator

3.1生成器的定义

得到生成器的方式

1.通过列表推导式得到生成器。

不同的是,列表推导式用的是方括号,而生成器用的是圆括号。

#列表推导式
new_list = [x * 3 for x in range(20)]  # list
print(type(new_list))

#生成器
new_list = (x * 3 for x in range(20))  # generator
print(type(new_list))

输出结果为

 <class 'list'>
<class 'generator'>

 2.借助函数完成

只要函数中出现了yield关键字,说明函数不再是函数了,而是生成器。

 步骤:

1.定义一个函数,函数中使用yield关键字

2.调用函数,接受调用的结果

3.得到的结果就是生成器

4.借助于next(),__next__()得到元素

例如:

def math():
    n = 1
    while n < 5:
        yield n  # 相当于return + 暂停
        n += 1


r = math()
print(r.__next__())
print(next(r))

 运行结果

1
2

3.2使用生成器

1.通过调用__next__()方式得到元素

2.next(生成器对象) builtins内置函数  每调用一次next生成一个元素

new_list = (x * 3 for x in range(20))  # generator
print(new_list.__next__())
print(new_list.__next__())
print(new_list.__next__())
print(next(new_list))
print(next(new_list))
print(next(new_list))

运行结果

0
3
6
9
12
15 

3.3用生成器实现斐波那契额数列

#定义生成器
def fib(n):
    a = 0
    b = 1
    i=0
    while i < n:
        yield b     # 相当于return + 暂停
        a, b = b, a + b
        i += 1
    return '没有数了'


g = fib(5)
for i in g:
    print(i)

结果:

1
1
2
3
5

3.4生成器的方法

__next__(): 获取下一个元素

send(value):向每次生成器调用中传值,注意:第一次调用send(None)

4.迭代器

迭代是访问集合元素的一种方式。

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

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束

迭代器只能往前不会后退

可以被next()函数调用并不断返回下一个值的对象称为迭代器: Iterator.

可迭代的

1.生成器 2.元组 3.列表 集合 字典 字符串

# 判断一个对象是否可迭代

用isinstance()函数来判断

from collections import Iterable
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
f = isinstance(list1, Iterable)
print(f)

运行结果

True

 在导入包的时候,如果是报错

from collections import Iterable
ImportError: cannot import name 'Iterable' from 'collections'

 是因为Iterable以及以下collections的方法都在3.10版本后被取消了。所以需要用

from collections.abc import Iterable来导入包。

注意:

生成器是可迭代的,也是迭代器。

list是可迭代的,但不是迭代器。

可以用iter函数可以让可迭代的变成迭代器。

例如:

list1 = (1, 2, 3, 4, 5, 6, 7, 8)
iter1 = iter(list1)
print(type(iter1))

运行结果:

<class 'tuple_iterator'>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值