python 迭代器,生成器和装饰器
1)可迭代对象包含迭代器
2)如果一个对象拥有__iter_方法,其是可迭代对象;如果一个对象拥有__next__方法,其就是迭代器
3)定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__方法和__next__方法
Python函数的定义体中有yield关键字,该函数就是生成器函数。调用生成器函数时,会返回一个生成器对象,也就是说,生成器函数时生成器工厂 ,generator
生成器和迭代器是相对而言的,生成器是自动生成值(如自动创建list),迭代器是自动取值(for i in range(5))。
装饰器
装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。装饰器的返回值也是一个函数对象。简单的说装饰器就是一个用来返回函数的函数。装饰器分为 类装饰器、方法装饰器。
1.函数装饰器在被装饰的函数定义之后立即运行。
2.被装饰的函数只在明确调用时运行。(不在装饰函数中明确调用被装饰函数,被装饰函数不会主动运行)
3.装饰器返回的应该是函数调用func而不是函数的运行结果func(),这也就是函数加不加括号的区别。
类装饰器
类装饰器实际上很简单,使用上和方法装饰器一样,只是要在装饰类中多定义一个__call__方法,这样在类作为装饰器装饰函数时,函数运行时就会运行__call__方法中的内容,完成类作为函数装饰器的作用。
class animal: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print('working here') res = self.func(*args, **kwargs) return res @animal def test(name, kind): word = f'{name} belongs to {kind}' return word A = test('cow','mammals') print(type(test)) print(A)
返回值:
working here <class '__main__.animal'> cow belongs to mammals
方法装饰器:
def timer(func): """ 用于计时的装饰器函数 使用装饰器时在函数前一行加上@timer即可 :param func: 被装饰函数 :return: 闭包函数,封装了自定义行为与被装饰函数的调用 """ def wrapper(*args, **kwargs): """ 闭包函数 :param args: 被装饰函数的位置参数 :param kwargs: 被装饰函数的关键字参数 :return: int,被装饰函数的计算结果 """ t1 = time.time() # 开始时间 r = func(*args, **kwargs) # 被装饰函数调用 t2 = time.time() # 结束时间 cost = t2 - t1 # 计算时长 print('function cost{} second'.format(cost)) return r return wrapper
装饰器传参数给被装饰函数:
from functools import wraps def dec(func): @wraps(func) def wrapper(*args, **kwargs): kwargs['name'] = 'no' kwargs['value'] = 'v' return func(*args, **kwargs) return wrapper @dec def foo(p1, p2, p3, name, value, p4='a'): print('p1: {}, p2: {}, p3:{}, name: {}, value:{}, p4: {}'.format( p1, p2, p3, name, value, p4 )) # p1,p2, p3是位置参数 # name,value 是关键字参数 # p4 默认参数 foo('a', 'b', 'c') foo('a1', 'b1', 'c1', name = 'name')