1.from functools import wraps
这个函数可以保留原来函数的属性
# from functools import wraps def car_time(fun): # @wraps(fun) def inner(*args,**kwargs): ret = fun(*args,**kwargs) return ret return inner @car_time def car(some): """ 这是一个函数car的注释""" print(some) print(car.__name__) print(car.__doc__) car('hello')
hello
inner
None
在这是掉functools模块的调用以后,可以看出,我们调用的函数 car() 实际是闭包函数里面的inner()函数。如果加入functools模块呢
from functools import wraps def car_time(fun): @wraps(fun) def inner(*args,**kwargs): print('装饰前') ret = fun(*args,**kwargs) print('装饰后') return ret return inner @car_time def car(some): """ 这是一个函数car的注释""" print(some) print(car.__name__) print(car.__doc__) car('hello') 装饰前 hello car 这是一个函数car的注释 装饰后
亲爱的詹姆斯先生,神不知鬼不觉的给你加了个装饰器。没改变函数的任何属性,岂不是美滋滋?我们用了都说好
带参数的装饰器
在装饰器外面再加一层函数,三层函数调用。
def outer(形参): def wrapper(func): def inner(*args,**kwargs): ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用 return ret return inner return wrapper @outer(实参) def func(): pass
多个装饰器装饰一个函数
这个有空再补。。。
迭代器
小定义:只要含有 __iter__ 方法都是可迭代的,内部含有 __next__ 和 __iter__ 方法就是迭代器。
l1 = 'abc' l2 = [1,2,3] l3 = {} print(l1.__iter__()) print(l2.__iter__()) print(l3.__iter__()) <str_iterator object at 0x000001B7BEF0BDA0> <list_iterator object at 0x000001B7BEF0BE80> <dict_keyiterator object at 0x000001B7BD2487C8>
这些可迭代的字符串,列表,字典等,执行了 __iter__() 方法,就是一个迭代器
l2 = [1,2,3,4,5] l3 = l2.__iter__() print(l3.__next__()) print(l3.__next__()) print(l3.__next__()) print(l3.__next__()) print(l3.__next__()) 1 2 3 4 5
对迭代器执行__next__()方法,便可以取出迭代器的一个一个的值
from collections import Iterable from collections import Iterator class ABC: def __iter__(self):pass def __next__(self):pass a = ABC() print(isinstance(a,Iterable)) print(isinstance(a,Iterator)) True True
此处我们定义一个类,给他__iter__() 和 __next__() 方法。isinstance()函数判断已知函数是否是已知的类型
简单的小结一下:
# 迭代器协议和可迭代协议
# 可以被for循环的都是可迭代的
# 可迭代的内部都有__iter__方法
# 只要是迭代器 一定可迭代
# 可迭代的.__iter__()方法就可以得到一个迭代器
# 迭代器中的__next__()方法可以一个一个的获取值
# for循环就是在使用迭代器