一、可迭代
一组数据,可以使用for循环就是可迭代的。如python中的字符串、列表、字典、集合、元组。
二、迭代器
迭代器都是可迭代的,且迭代器可以使用next()方法。
from collections.abc import Iterable, Iterator
class MyDatas:
def __init__(self, n):
# 传入参数,使用列表推导式生成一个列表
self.data = [i for i in range(1, n + 1)]
# 当前索引
self.current_index = 0
# 获取迭代器方法
def __iter__(self):
return self
# 迭代器的next方法,依赖与__iter__方法
def __next__(self):
if self.current_index >= len(self.data):
raise IndexError("取完了")
else:
result = self.data[self.current_index]
self.current_index += 1
return result
md = MyDatas(5)
# print(md)
# 判断实例md是否是可迭代的,是否是迭代器
print(isinstance(md, Iterable), isinstance(md, Iterator))
# next(md)
while True:
try: # 捕获异常
print(next(md))
except IndexError as e:
# 返回异常对象e
print(e)
break
三、生成器
生成器包含一组生成规则,生成器是装饰器,但生成器不能使用下标索引查找。当数据较多时,使用生成器更省内存。如元组推导式生成的就是一个生成器。
from collections.abc import Iterable, Iterator, Generator
# 生成器
def my_datas():
# 使用yield声明生成元素
yield 1
yield 2
yield 3
yield 10
return 100 # 不起平常使用的作用
r = my_datas()
print(r)
print(type(r)) # 返回生成器类型
for i in my_datas():
print(i)
while True:
try:
print(next(r)) # 捕获异常
except StopIteration as e:
print("取完了", e) # return的值赋值给e
break
# 列表推导式
l0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(l0.__sizeof__()) # 返回占用内存
# 元组推导式
t0 = (i for i in range(100))
print(t0.__sizeof__()) # 不能使用索引
# 生成器是可迭代的,是迭代器
print(isinstance(t0, Iterable), isinstance(t0, Iterator), isinstance(t0, Generator))
四、装饰器
装饰器本质是闭包,在不改变原函数结构的情况下为函数添加新功能。
# 装饰器
def cost_time(f):
def calc():
start = time.time()
# 运行原有参数
f()
print(f"函数{f.__name__}开销:{time.time() - start}")
# calc()
return calc
datas = [random.randint(0, 10000) for i in range(10000)]
datas2 = datas.copy()
# 使用@将原函数作为参数传递
@cost_time
def my_sort1():
datas.sort(reverse=True)
print(datas)
@cost_time
def my_sort2():
datas3 = sorted(datas2, reverse=True)
print(datas3)
my_sort1()
my_sort2()