|
一、装饰器
参考:https://zhuanlan.zhihu.com/p/87353829
https://blog.csdn.net/zhh763984017/article/details/120072425
将函数作为对象
闭包概念
- def outer(x):
- def inner(y):
- return x+y
- return inner # 返回一个函数对象
复制代码 装饰器就是一个闭包,是在原有函数功能上的一个拓展
1、无参数的装饰器:
- def cost_time(func):
- def inner():
- print(f'start time{time.time()}')
- func()
- return inner
- @ cost_time
- def time_sleep():
- time.sleep(5) # 在函数中加入新的功能实现
复制代码 2、装饰器传参:
被装饰的函数带有参数- def cost_time(func):
- def inner(*args, **kwargs):
- print(time.time())
- func(*args, **kwargs)
- @cost_time
- def time_sleep(name):
- print(f'进程名字:{name}')
- time.sleep(5)
复制代码 3、带参数的装饰器
装饰器函数带有参数,在@的时候需要传入一些必要的参数- import time
-
-
- def count_time_args(msg=None): # 需要多加一层函数,引入传参
- def count_time(func):
- def wrapper(*args, **kwargs):
- t1 = time.time()
- func(*args, **kwargs)
- print(f"[{msg}]执行时间为:", time.time() - t1)
-
- return wrapper
-
- return count_time
-
-
- @count_time_args(msg="baiyu")
- def fun_one():
- time.sleep(1)
-
-
- @count_time_args(msg="zhh")
- def fun_two():
- time.sleep(1)
-
-
- @count_time_args(msg="mylove")
- def fun_three():
- time.sleep(1)
-
-
- if __name__ == '__main__':
- fun_one()
- fun_two()
- fun_three()
复制代码 二、类装饰器
当我们将类作为一个装饰器,工作流程:
通过__init__()方法初始化类
通过__call__()方法调用真正的装饰方法
1、不带参数的类装饰器
- import time
-
-
- class BaiyuDecorator:
- def __init__(self, func):
- self.func = func
- print("执行类的__init__方法")
-
- def __call__(self, *args, **kwargs):
- print('进入__call__函数')
- t1 = time.time()
- self.func(*args, **kwargs)
- print("执行时间为:", time.time() - t1)
-
-
- @BaiyuDecorator
- def baiyu():
- print("我是攻城狮白玉")
- time.sleep(2)
-
-
- def python_blog_list():
- time.sleep(5)
- print('''【Python】爬虫实战,零基础初试爬虫下载图片(附源码和分析过程)
- https://blog.csdn.net/zhh763984017/article/details/119063252 ''')
- print('''【Python】除了多线程和多进程,你还要会协程
- https://blog.csdn.net/zhh763984017/article/details/118958668 ''')
- print('''【Python】爬虫提速小技巧,多线程与多进程(附源码示例)
- https://blog.csdn.net/zhh763984017/article/details/118773313 ''')
- print('''【Python】爬虫解析利器Xpath,由浅入深快速掌握(附源码例子)
- https://blog.csdn.net/zhh763984017/article/details/118634945 ''')
-
-
- @BaiyuDecorator
- def blog(name):
- print('进入blog函数')
- name()
- print('我的博客是 https://blog.csdn.net/zhh763984017')
-
-
- if __name__ == '__main__':
- baiyu()
- print('--------------')
- blog(python_blog_list)
复制代码 2、带参数的装饰器:
当装饰器有参数的时候,init() 函数就不能传入func(func代表要装饰的函数)了,而func是在__call__函数调用的时候传入的。- class BaiyuDecorator:
- def __init__(self, arg1, arg2): # init()方法里面的参数都是装饰器的参数
- print('执行类Decorator的__init__()方法')
- self.arg1 = arg1
- self.arg2 = arg2
-
- def __call__(self, func): # 因为装饰器带了参数,所以接收传入函数变量的位置是这里
- print('执行类Decorator的__call__()方法')
-
- def baiyu_warp(*args): # 这里装饰器的函数名字可以随便命名,只要跟return的函数名相同即可
- print('执行wrap()')
- print('装饰器参数:', self.arg1, self.arg2)
- print('执行' + func.__name__ + '()')
- func(*args)
- print(func.__name__ + '()执行完毕')
-
- return baiyu_warp
-
-
- @BaiyuDecorator('Hello', 'Baiyu')
- def example(a1, a2, a3):
- print('传入example()的参数:', a1, a2, a3)
-
-
- if __name__ == '__main__':
- print('准备调用example()')
- example('Baiyu', 'Happy', 'Coder')
- print('测试代码执行完毕')
复制代码 三、装饰器的执行顺序是从里到外的。
来源:https://www.cnblogs.com/mine-l/p/17567946.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|