Python装饰器

目录

官方定义

函数装饰器的使用

实现一个最简单的装饰器

多装饰器嵌套

带参数的装饰器

装饰器内获取被修改函数的属性

类装饰器的使用

参考资料


官方定义

        装饰器本质上是一个Python函数,它可以让被装饰函数或方法在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器一般采用语法糖的形式,是一种语法格式。比如:@property,@wraps()。

函数装饰器的使用

实现一个最简单的装饰器

        使用装饰器可以将一些通用的功能从函数中抽离出来。

        给出一个示例函数

import time


def log():
    print('start!')
    time.sleep(5)
    print('log')
    print('end!')


log()


------------------
start!
log
end!

        使用装饰器的写法

import time


def sleep(func):
    def inner():
        print('start!')
        time.sleep(5)
        func()
        print('end!')

    return inner
        

@sleep
# 相当于sleep(log())
def log():
    print('log')


log()


------------------
start!
log
end!

多装饰器嵌套

        多个装饰器时是依次嵌套执行的

import time


def sleep1(func):
    def inner():
        print('start!sleep1')
        time.sleep(5)
        func()
        print('end!sleep1')

    return inner


def sleep2(func):
    def inner():
        print('start!sleep2')
        time.sleep(5)
        func()
        print('end!sleep2')

    return inner
        

@sleep1
@sleep2
# 相当于sleep1(sleep2(log()))
def log():
    print('log')


log()


------------------
start!sleep1
start!sleep2
log
end!sleep2
end!sleep1

带参数的装饰器

        由于装饰器只能接收一个参数,并且还是函数类型。所以如果想向装饰器传递其他参数,正确的写法应该是在装饰器外面再包裹上一个函数,让最外面的函数接收参数,返回的是装饰器,因为@符号后面必须是装饰器实例。

import time


def setTime(second):
    def sleep(func):
        def inner():
            print('start!'second)
            time.sleep(second)
            func()
            print('end!'second)

        return inner
    return sleep
        

@setTime(5)
def log():
    print('log')


log()


------------------
start!5
log
end!5

装饰器内获取被修改函数的属性

        函数传入装饰器后会失去它原先的属性,比如参数。这时就需要用到@wraps装饰器了。

import time
from functools import wraps


def setTime(second):
    def sleep(func):
        @wraps(func)
        def inner(*args, **kwargs):
            print('start!', func.__module__, func.__name__, second)
            time.sleep(second)
            func(*args, **kwargs)
            print('end!', func.__module__, func.__name__, second)

        return inner
    return sleep
        

@setTime(5)
def log(msg):
    print(msg)


log('log')


------------------
start! __main__ log 5
log
end! __main__ log 5

类装饰器的使用

        类装饰器这个写法,主要思路就是返回一个增加了新功能的函数对象,只不过这个函数对象是一个类的实例对象。由于装饰器是可调用对象,所以必须在类里面实现__call__方法,这样由类生成的各种实例加上()就可以运行了。因为与函数装饰器是类似的,所以这里只展示一个最复杂的用法,装饰器带参数,且被装饰函数也带参数。

import time
from functools import wraps


class Decorator:
    def __init__(self, second):
        self.second = second

    def __call__(self, func,*args, **kwargs):
        @wraps(func)
        def inner(*args, **kwargs):
            print('start!', func.__module__, func.__name__, self.second)
            time.sleep(self.second)
            func(*args, **kwargs)
            print('end!', func.__module__, func.__name__, self.second)

        return inner
        

@Decorator(5)
def log(msg):
    print(msg)


log('log')


------------------
start! __main__ log 5
log
end! __main__ log 5

参考资料

python中带有参数的装饰器_python 带参数的装饰器_IT之一小佬的博客-CSDN博客

 python装饰器——获取被修饰的函数参数_python 装饰器获取被装饰函数属性_松子吃松子的博客-CSDN博客

python装饰器——获取被修饰的函数参数_python 装饰器获取被装饰函数属性_松子吃松子的博客-CSDN博客

python类装饰器详解-Python 类装饰器解析 (taodudu.cc)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值