一、可迭代对象
可迭代对象是指可以返回一个迭代器的对象(可迭代对象是指可以被 for
循环遍历的对象)。任何实现了 __iter__()
方法或者 __getitem__()
方法的对象都被认为是可迭代的。常见的可迭代对象包括列表、元组、字符串、字典和集合。
# 可迭代
from collections.abc import Iterable
# 迭代器
from collections.abc import Iterator
i = 100
s = "hello"
l = [1, 2, 3]
t = (1, 2, 3)
d = {"name": "qiku"}
set0 = {1, 2, 3}
print(isinstance(i, Iterable), isinstance(s, Iterable), isinstance(l, Iterable), isinstance(t, Iterable),
isinstance(d, Iterable),
isinstance(set0, Iterable))
t0 = (i for i in range(10))
print(isinstance(t0, Iterator), next(t0), next(t0), next(t0))
二、迭代器
迭代器是一个实现了 __iter__()
和 __next__()【
用于获取数据流中的下一个项(每次获取一个)】
方法的对象。迭代器不仅是可迭代的,而且它自己可以被用于获取下一个值。所有迭代器都是可迭代的,但不是所有可迭代对象都是迭代器。(迭代器可以被 next()
函数或 for
循环使用)
(for循环与next分开运行,方便观察)
# 可迭代
from collections.abc import Iterable
# 迭代器
from collections.abc import Iterator
class MyDatas:
def __init__(self, n):
self.datas = [i for i in range(1, n + 1)]
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index >= len(self.datas):
raise IndexError
else:
current = self.datas[self.current_index]
self.current_index += 1
return current
md = MyDatas(6)
print(isinstance(md, Iterable), isinstance(md, Iterator))
for e in md:
print(e)
print(next(md))
print(next(md))
print(next(md))
print(next(md))
print(next(md))
print(next(md))
print(next(md))
for循环运行结果:
next运行结果:
三、生成器
生成器是特殊类型的迭代器,用于简化迭代过程(每次迭代时,生成器会返回一个值,并在下一次迭代时从上次停止的地方继续执行)。生成器通过 yield
关键字来生成值,而不是像普通函数那样返回一个值。每次调用生成器的next()方法时,生成器会从上次 yield
语句处继续执行,直到遇到下一个 yield
或者结束。
1.__sizeof__()方法, next()取值
# 可迭代
from collections.abc import Iterable
# 迭代器
from collections.abc import Iterator
# 生成器
from collections.abc import Generator
l0 = [1, 2, 3, 4, 5, 6]
print(l0.__sizeof__())
print(l0[5])
t0 = (i for i in range(1, 100))
print(t0.__sizeof__())
print(isinstance(t0, Iterable), isinstance(t0, Iterator), isinstance(t0, Generator))
print(next(t0), next(t0))
2.yield语句
(for 循环取值,取不到return的返回值)
def my_datas():
yield 1
yield 10
yield 30
return 200
r = my_datas()
print(type(r))
# 永远无法取到return的200
for i in my_datas():
print(i)
(使用python异常处理可以取到return返回的值)
def my_datas():
yield 1
yield 10
yield 30
return 200
r = my_datas()
print(type(r))
while True:
try:
print(next(r))
except StopIteration as e:
print("end", e)
break
四、装饰器
装饰器是一个函数或类,用于在不修改原有代码的情况下添加新功能。装饰器通常用于添加日志记录、性能测试、事务处理等。
(闭包, 三大特性:1.外部函数嵌套内部函数;2.外部函数返回内部函数;3.内部函数可以访问外部函数局部变量)
时间开销:
import random
import time
# 装饰器
def cost_time(f):
def calc():
start = time.time()
f()
print(f"{f.__name__}开销:{time.time()-start}")
return calc
cost_time(lambda: print("--"))()
datas = [random.randint(0, 10000) for i in range(1000)]
datas_copy = datas.copy()
@cost_time
def my_fun1():
datas.sort(reverse=True)
print(datas)
# my_fun1 = cost_time(my_fun1)
my_fun1()
@cost_time
def my_fun2():
new_list = sorted(datas_copy, reverse=True)
print(new_list)
# my_fun2 = cost_time(my_fun2)
my_fun2()