今世 发表于 2023-7-20 20:52:34

秋招--1、装饰器

一、装饰器

参考: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】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 秋招--1、装饰器