python的三大神器: 装饰器 迭代器 生成器
一、装饰器
装饰器 decorator,是对函数的一种包装。
它能使函数的功能得到扩充,而同时不用修改函数本身的代码。
它能够增加函数执行前、执行后的行为,而不需对调用函数的代码做任何改变。
例子:
def wapper(func):
def inner():
print("执行function——a之前")
func()
print("执行function——a之后")
return None
return inner
@wapper
def a():
print("执行function——a")
if __name__ == '__main__':
a()
执行结果
一般我们只在函数执行前添加功能,所以写成如下形式
def wapper(func):
def inner():
print("执行function——a之前")
return func()
return inner
@wapper
def a():
print("执行function——a")
if __name__ == '__main__':
a()
装饰器的执行顺序如下,下面代码的功能就相当于给 b() 添加了一个 @wapper 装饰器
然后执行 b()
def wapper(func):
def inner():
# print("KKKKKKKKKKKKKKKKKKKKKKKKK")
# print(args)
# print(kwargs)
print("执行function——b之前")
return func()
return inner
def b():
print("执行function——b")
if __name__ == '__main__':
f = b
s = wapper(f)
s()
被装饰函数传递参数问题
def wapper(func):
def inner(*args, **kwargs):
print("执行function——a之前")
print("传递的参数")
print(args)
print(kwargs)
return func(*args, **kwargs)
return inner
@wapper
def a(num1, num2=5):
print("执行function——a")
print(num1)
print(num2)
if __name__ == '__main__':
a(2, num2=56)
装饰器工厂函数——装饰器可以传递参数
def func1(*args, **kwargs): # 接受@func1的参数
print("装饰器参数:", args, kwargs)
def func2(func):
def func3():
print("执行function——a之前")
return func()
return func3
return func2
@func1(2, g=9)
def a():
print("执行function——a")
if __name__ == '__main__':
a()
迭代器
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__方法(Python3中是对象的__next__方法,Python2中是对象的next()方法)。
list1 = [1, 2, 3, 4, 5]
# 通过iter创建迭代器对象
it = iter(list1)
# 通过next()函数依次遍历迭代器
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
当迭代完成的时候如果继续迭代会出现异常
可以通过for循环遍历迭代器
list1 = [1, 2, 3, 4, 5]
# 通过iter创建迭代器对象
it = iter(list1)
# 通过next()函数依次遍历迭代器
for i in it:
print(i, end=" ")
自定义迭代器:
要想构造一个迭代器,就要实现它的__next__方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
# 实例化自定义迭代器
myclass = MyNumbers()
# 创建迭代器对象
myiter = iter(myclass)
for i in myiter:
print(i, end=" ")
生成器
生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行,生成器本质上是特殊的迭代器
自定义一个生成器函数输出斐波拉契数列
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if counter > n:
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print(next(f), end=" ")
except StopIteration:
sys.exit()
send() 的用法
在获取下一个值的时候,send和next效果是一样的
但是,send可以和生成器交互,在获取下一个值的时候,给上一yield的位置传递一个数据。第一次使用生成器的时候 是用next获取下一个值,最后一个yield不能接受外部的值
def send_generator():
print("######################")
content = yield 1
# content就是同send传递过来的
print('=======', content)
print("@@@@@@@@@@@@@@@@@@@@@@")
yield 2
g = send_generator()
ret = g.__next__()
print('============', ret)
ret = g.send('hello') # 此处send的效果和next一样
print('============', ret)