翼度科技»论坛 编程开发 python 查看内容

秋招--1、装饰器

2

主题

2

帖子

6

积分

新手上路

Rank: 1

积分
6
一、装饰器

参考:https://zhuanlan.zhihu.com/p/87353829
https://blog.csdn.net/zhh763984017/article/details/120072425
将函数作为对象
闭包概念
  1. def outer(x):
  2.   def inner(y):
  3.     return x+y
  4.   return inner        # 返回一个函数对象
复制代码
装饰器就是一个闭包,是在原有函数功能上的一个拓展

1、无参数的装饰器:
  1. def cost_time(func):
  2.   def inner():
  3.     print(f'start time{time.time()}')
  4.     func()
  5.   return inner
  6. @ cost_time
  7. def time_sleep():
  8.   time.sleep(5)  # 在函数中加入新的功能实现
复制代码
2、装饰器传参:

被装饰的函数带有参数
  1. def cost_time(func):
  2.   def inner(*args, **kwargs):
  3.     print(time.time())
  4.     func(*args, **kwargs)
  5. @cost_time
  6. def time_sleep(name):
  7.   print(f'进程名字:{name}')
  8.   time.sleep(5)
复制代码
3、带参数的装饰器

装饰器函数带有参数,在@的时候需要传入一些必要的参数
  1. import time
  2. def count_time_args(msg=None):   # 需要多加一层函数,引入传参
  3.     def count_time(func):
  4.         def wrapper(*args, **kwargs):
  5.             t1 = time.time()
  6.             func(*args, **kwargs)
  7.             print(f"[{msg}]执行时间为:", time.time() - t1)
  8.         return wrapper
  9.     return count_time
  10. @count_time_args(msg="baiyu")
  11. def fun_one():
  12.     time.sleep(1)
  13. @count_time_args(msg="zhh")
  14. def fun_two():
  15.     time.sleep(1)
  16. @count_time_args(msg="mylove")
  17. def fun_three():
  18.     time.sleep(1)
  19. if __name__ == '__main__':
  20.     fun_one()
  21.     fun_two()
  22.     fun_three()
复制代码
二、类装饰器

当我们将类作为一个装饰器,工作流程:
通过__init__()方法初始化类
通过__call__()方法调用真正的装饰方法
1、不带参数的类装饰器
  1. import time
  2. class BaiyuDecorator:
  3.     def __init__(self, func):
  4.         self.func = func
  5.         print("执行类的__init__方法")
  6.     def __call__(self, *args, **kwargs):
  7.         print('进入__call__函数')
  8.         t1 = time.time()
  9.         self.func(*args, **kwargs)
  10.         print("执行时间为:", time.time() - t1)
  11. @BaiyuDecorator
  12. def baiyu():
  13.     print("我是攻城狮白玉")
  14.     time.sleep(2)
  15. def python_blog_list():
  16.     time.sleep(5)
  17.     print('''【Python】爬虫实战,零基础初试爬虫下载图片(附源码和分析过程)
  18.     https://blog.csdn.net/zhh763984017/article/details/119063252 ''')
  19.     print('''【Python】除了多线程和多进程,你还要会协程
  20.     https://blog.csdn.net/zhh763984017/article/details/118958668 ''')
  21.     print('''【Python】爬虫提速小技巧,多线程与多进程(附源码示例)
  22.     https://blog.csdn.net/zhh763984017/article/details/118773313 ''')
  23.     print('''【Python】爬虫解析利器Xpath,由浅入深快速掌握(附源码例子)
  24.     https://blog.csdn.net/zhh763984017/article/details/118634945 ''')
  25. @BaiyuDecorator
  26. def blog(name):
  27.     print('进入blog函数')
  28.     name()
  29.     print('我的博客是 https://blog.csdn.net/zhh763984017')
  30. if __name__ == '__main__':
  31.     baiyu()
  32.     print('--------------')
  33.     blog(python_blog_list)
复制代码
2、带参数的装饰器:

当装饰器有参数的时候,init() 函数就不能传入func(func代表要装饰的函数)了,而func是在__call__函数调用的时候传入的。
  1. class BaiyuDecorator:
  2.     def __init__(self, arg1, arg2):  # init()方法里面的参数都是装饰器的参数
  3.         print('执行类Decorator的__init__()方法')
  4.         self.arg1 = arg1
  5.         self.arg2 = arg2
  6.     def __call__(self, func):  # 因为装饰器带了参数,所以接收传入函数变量的位置是这里
  7.         print('执行类Decorator的__call__()方法')
  8.         def baiyu_warp(*args):  # 这里装饰器的函数名字可以随便命名,只要跟return的函数名相同即可
  9.             print('执行wrap()')
  10.             print('装饰器参数:', self.arg1, self.arg2)
  11.             print('执行' + func.__name__ + '()')
  12.             func(*args)
  13.             print(func.__name__ + '()执行完毕')
  14.         return baiyu_warp
  15. @BaiyuDecorator('Hello', 'Baiyu')
  16. def example(a1, a2, a3):
  17.     print('传入example()的参数:', a1, a2, a3)
  18. if __name__ == '__main__':
  19.     print('准备调用example()')
  20.     example('Baiyu', 'Happy', 'Coder')
  21.     print('测试代码执行完毕')
复制代码
三、装饰器的执行顺序是从里到外的。


来源:https://www.cnblogs.com/mine-l/p/17567946.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具