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
​
posted @ 2022-09-09 09:25  无敌大牛牛  阅读(45)  评论(0编辑  收藏  举报