python装饰器、迭代器、生成器
无参装饰器
def count_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return res
return wrapper
"""
只要运行语法糖这行代码(@count_time),就会立刻调用这个装饰器功能,然后把要装饰的函数地址传进去即:count_time(home) 最后把得到的结果赋值给原函数名,home = count_time(home)
"""
@count_time
def home():
print("dhdh")
time.sleep(2)
print("haha")
return "home函数的返回值"
print(home())
有参装饰器
def gouter(x):
def outer(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
return res
return wrapper
return outer
迭代器
什么是可迭代对象(可以迭代的对象)?
简单的理解,就是能被for循环遍历的,就是可迭代对象;
准确的说,就是内置有
__iter__()
方法的就可以称之为可迭代对象
什么是迭代器?
迭代就是重复,但每次都重复;都是在上一次的基础上做的,并不是单纯的重复;
迭代的每一次重复,都跟上一次的结果是有关联的
迭代器:不依赖于索引的迭代取值方式
当调用可迭代对象下的
__iter__()
方法后,就会得到一个迭代器,或者说:把可迭代对象,转换为迭代器对象只要是迭代器对象,它内置就会有一个
__next__()
方法
可迭代对象:可以转换为迭代器的对象
总结
迭代器对象:即要内置有
__next__
()方法,并且还内置有__iter__()
方法的对象迭代器对象每调用
__next__()
方法,就会得到迭代器的下一个值迭代器对象调用
__iter__()
方法,得到是迭代器本身(和没调是一样的)
for循环原理
# 迭代器对象调用`__iter__()`方法,得到是迭代器本身(和没调是一样的),为什么这样设计呢?
for i in 可迭代对象.__iter__(): # 如果是可迭代对象调用这个__iter__()方法,得到迭代器对象
pass
for i in 迭代器对象.__iter__():# 迭代器对象调用__iter__()方法以后,得到的就是迭代器本身
pass # 这样设计也就是为了能够同一套规则能够处理
for key in d:
print(key)
# for运行机制解读
# 1。d是一个可迭代对象,首先调用d.__iter__()方法,得到一个迭代器版本
# 2。调用迭代器对象的__next__()方法,拿到一个返回值赋值给key
# 3。循环执行第二步的操作,只到抛出StopIteration异常,捕获异常后结束循环
# 这也是为什么for循环也称之为:迭代循环
# 而while循环称之为,条件循环
d = {"key1": "value1", "key2": "value2", "key3": "value3"}
res = d.__iter__() # 返回一个迭代器对象
print(res) # <dict_keyiterator object at 0x000001990DF9DC78>
print(res.__next__()) # 通过迭代器对象的__next__方法进行取值
print(res.__next__())
print(res.__next__())
print(res.__next__()) # StopIteration,当所有值取完以后,再运行就会报这个错误
#################通过while循环取字典中的值####################
d = {"key1": "value1", "key2": "value2", "key3": "value3"}
res = d.__iter__() # 返回一个迭代器对象
while True:
try:
print(d[res.__next__()])
except StopIteration:
break
# 小知识
str = "abcd"
len(str) 和 str.__len__() 方法是一样的
# 所以__iter__() 可以写成 iter()
# __next__() 可以写成 next()
生成器
生成器就是我们自己定义的迭代器
关键字yield
def func():
print("第一次执行")
yield 1
print("第二次执行")
yield 2
print("第三次执行")
yield 3
print("第四次执行")
yield 4
print("第五次执行")
func = iter(func())
res = next(func)
print(res)
res = next(func)
print(res)
res = next(func)
print(res)
res = next(func)
print(res)
res = next(func)
print(res) # 当第五次执行的时候 ,因为没有yield所以会报StopIteration