Python之装饰器

系统 1399 0

功能:

为已存在的函数或对象添加额外的功能

 

原则:

  • 不改变源代码为其添加功能
  • 不改变函数的调用方式

 

方法:

装饰器 = 高阶函数 + 嵌套函数

(高阶函数:一个函数可以作为参数传递给另外一个函数,或者,一个函数的返回值是一个函数,即函数的入口地址)

  1. 函数名作为参数传递给装饰器(@decorator_name)
  2. 装饰函数返回函数名(函数地址)

注意:

  1. 默认情况下,装饰器会修改名字和文档说明,但是可以使用 functools 中 的 @wraps() 解决。@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
            
              def decorator(func):
    """
    decorator __doc__
    """
    # @wraps(func)
    def wrapper(*args, **kwargs):
        """wrapper __doc__"""
        func()
    return wrapper


@decorator
def test():
    """test __doc__"""
    time.sleep(0.5)


test(1, 2)
print("function name:", test.__name__)
print("function doc :", test.__doc__)

# output:
# function name: wrapper
# function doc : wrapper __doc__

# 加了@wraps(func)后的output:
# function name: test
# function doc : test __doc__
            
          

 

 

例子:

1. 函数作为装饰器

此例子实现了一个计算调用函数所占用的时间

            
              import time
from functools import wraps


def decorator(func):
    """
    function:decorator
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        """function:wrapper"""
        start = time.time()
        ret = func(*args, **kwargs)
        end = time.time()
        print("function {0} run time: {1}".format(func.__name__, end - start))
        # print("function {fun} run time: {time}".format(fun=func.__name__, time=end - start))
        return ret
    return wrapper


@decorator
def test(a, b, name="Lizo"):
    """function:test"""
    time.sleep(0.5)
    print(a, b, name)

            
          

2.类作为装饰器

为什么可以使用类作为装饰器?因为在Python中,一切皆对象,其实函数也是一个对象,如果一个类实现了  __call__(self) 方法后,就可以像调用函数一样,直接加一个括号就可以调用。

            
              class Runtime:
    def __init__(self):
        pass

    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start = time.time()
            ret = func(*args, **kwargs)
            end = time.time()
            print("function: {func} run time: {time}".format(func=func.__name__, time=end - start))
            return ret
        return wrapper


#使用装饰器方法1
runtime = Runtime()
@runtime
def test_class_decorator1():
    print("in the test_class_decorator")
    time.sleep(0.2)


#使用装饰器方法2
@Runtime()
def test_class_decorator2():
    print("in the test_class_decorator")
    time.sleep(0.2)
            
          

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论