Python - 三大神器 迭代器,生成器,装饰器
在介绍三大器之前先来了解一下容器和可迭代对象...
一.容器
容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:
- list, deque...
- set, frozensets(不可变集合)...
- dict, defaultdict, OrderedDict, Counter...
- tuple, namedtuple...
- str
容器的概念就像一个盒子,可以往里面装东西.当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuples都是容器对象:
Python提供一些语句和关键字用于访问可迭代对象的元素,比如for循环、列表解析、逻辑操作符等。
判断一个对象是否是可迭代对象:
1. 省内存 -> 生成器
2. 惰性机制
3. 只能向前. 不能反复
生成器函数 带yield的函数(1、返回值 2、保留函数的运行状态)
next(t) t.__next__ t.send(可以给上一层的yield传值)
# 用生成器函数
# yield 相当于return控制的是函数的返回值
# x=yield的另外一个特性,接收send传过来的值,赋值给x
def test():
print("开始啦")
first = yield # return 1 first = None
print("第一次",first)
yield 2
print("第二次")
t = test()
print(test().__next__())
res = t.__next__() # next(t)
print(res)
res = t.send("函数停留在first那个位置,我就是给first赋值的")
print(res)
输出结果
开始啦
None
开始啦
None
第一次 函数停留在first那个位置,我就是给first赋值的
2.生成器表达式
print(sum(i for i in range(10000))) # 表达式一般用for循环 (i for i in range(10000))
# 作用 节省内存,在内部已经实现了__iter__的方法
五.装饰器
1.装饰器的作用
- 装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功 能,
- 装饰器的返回值也是一个函数/类对象。
-
它有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用
2.不带参数的装饰器
def wrapper(func):
def inner(*args,**kwargs):
print('--函数前添加功能--')
ret = func(*args,**kwargs)
print('--函数后添加功能--')
return ret
return inner
#定义一个函数,并添加装饰器@wrapper #等价于 func1 = timer(func1)
def func1(m):
print('--func1--')
return m
#调用函数
f = func1(20)
print(f)
3.带参数的装饰器
def outer(flag):
def timer(func):
def inner(*args,**kwargs):
if flag:
print('--添加功能--')
ret = func(*args,**kwargs)
else:
ret = func(*args,**kwargs)
return ret
return inner
return timer
#定义函数并添加装饰器
@outer(True) # func1 = timer()
def func1(m):
print('--func1--')
return m
#调用函数
print(func1(20))
4.多个装饰器装饰一个函数
def wrapper1(func):
print('--wrapper1装饰--')
def inner1(*args,**kwargs):
print('--wrapper1 前--')
ret = func(*args,**kwargs)
print('--wrapper1 后--')
return ret
return inner1
def wrapper2(func):print('--wrapper2装饰--')
def inner2(*args,**kwargs):
print('--wrapper2 前--')
ret = func(*args,**kwargs)
print('--wrapper2 后--')
return ret
return inner2
#定义函数并添加装饰器@wrapper2 #func1 = wrapper2(func1) inner2 func = inner1
@wrapper1 #func1 = wrapper1(func1) inner1 func = func1
def func1(m):
print ('--func1--')
return m
#调用函数
print(func1(20))
#执行结果:# --开始装饰wrapper1-
# --开始装饰wrapper2-
# --wrapper2 前-# --wrapper1 前-
# --func1-# --wrapper1 后-
# --wrapper2 后-
# 20
5.装饰器修复技术
import time
from functools import wraps
def timer(func):
@wraps(func)
def inner():
print(time.time())
ret = func()
return ret
return inne
六.闭包
根据这句话,其实我们自己就可以总结出在python语言中形成闭包的三个条件,缺一不可:
1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套
2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量
3)外部函数必须返回内嵌函数——必须返回那个内部函数
python闭包的优点:
- 避免使用全局变量
- 可以提供部分数据的隐藏
- 可以提供更优雅的面向对象实现
def funx():
x=5
def funy():
nonlocal x
x+=1
return x
return funy