1. 迭代器
- 自定义迭代器对象: 在类里面提供__iter__和__next__方法创建的对象就是完整的迭代器(为什么说完整呢?)。
- 实际上严格意义来说只要类中实现了__iter__方法实现了, 这个类就是迭代器, 它返回了迭代器对象, 但是一个迭代器对象没有实现__next__方法, 这个迭代器是无法正常使用的, 这里验证了上面的结果
class MyIterator(object):
# 构造方法
def __init__(self, my_list):
self.my_list = my_list
self.current_index = 0
# 标志1
def __iter__(self):
return self
# 标志2,获取迭代器中下一个值
def __next__(self):
if self.current_index < len(self.my_list):
value = self.my_list[self.current_index]
# 取值完成以后需要对下标加上1
self.current_index += 1
return value
else:
# 超出范围抛出停止迭代的异常
raise StopIteration
# 迭代器被__iter__调用,返回一个迭代器
my = MyIterator([1, 2, 3, 4])
# print(next(my))
# print(next(my))
# print(next(my))
# print(next(my))
# 验证对象是否是迭代器的方法
from collections import Iterable
print(isinstance(my, Iterable))
2. 生成器
- 把列表推导式的中括号改成小括号创建的对象就是生成器。生成器:生成器是一个特殊的迭代器,也就是说可以使用next和for循环取值
print(type((i for i in range(10))))
# <class 'generator'>
yield就是保存当前程序的执行状态, 使用for循环的时候, 每次取一个元素的时候就会计算一次, 用yield实现的generator(生成器)和iterator(迭代器)一样, 它的好处是不用一次计算所有元素, 而是用一次算一次, 大大的节省空间, 由于generator每次计算需要上一次的计算结果, 所以yield就达到了这个作用, 如果用return, 上次的结果就没了.
# 最简单的生成器
def createGenerator():
my_list = range(3)
for i in my_list:
yield i * i
my_generator = createGenerator()
- 以下代码测试了yield和return不同之处之一—yield后面的代码可以正常执行, return 后面的代码不执行
# 生成器实现斐波那契数列
def fibonacci(num):
# num: 表示斐波那契数列的个数
# 保存数列的前两个值
a = 0
b = 1
# 记录生成数列的下标
current_index = 0
# 循环判断条件是否成立
while current_index < num:
# 记录当前斐波那契数值
result = a
# 这里实验了一下, yield和return不同之处之一---yield后面的代码可以正常执行, return 后面的代码不执行
# yield result
# 生成下一个斐波那契数值,即b,但下一次输出a
a, b = b, a + b
current_index += 1
# 代码执行到yield会暂停,把结果返回出取,再次启动生 成器的时候会在暂停的位置继续往下执行
yield result
# 生成器返回类型是特殊的迭代器(生成器)需要for/next()取值
generator = fibonacci(10)
for value in generator:
print(value)
3. 装饰器有写到过, 不多说直接上代码
# 外函数outer()
def outer():
# 外函数局部变量,对于内函数来说相当于全局变量(重点理解, 有助于理解闭包的延迟绑定)
number = 10
# 内函数
def inner():
# 外函数数据的引用
nonlocal number
number += 1
# 返回值是内函数inner的引用
return inner
# 调用outer函数,用func接收inner函数的引用
func = outer()
# 调用inner函数
func()
def outer(func):
def inner():
return func()
return inner
# 装饰器的使用 @ :相当于 func = outer(func)
# 即把func的引用替换成outer的返回值,也就是内函数的引用
# 然后在内函数中返回原本func的引用的调用,即func的函数体
@outer
def func():
pass
装饰器的使用场景
def outer(func):
print('验证前做的事')
def inner():
func()
print('验证后做的事')
return inner
@outer
def func():
print('验证代码')
func()
# 装饰器的另一种调用方法
# outer(func)()
装饰器的另一种使用(Flask中会用到)
def outer(func):
print('验证前做的事')
def inner():
func()
print('验证后做的事')
return inner
def func():
print('验证代码')
outer(func)()