Python函数装饰器(Decorator)

       Python函数装饰器(functional decorators)就是拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。

       这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌“原”函数的函数。

       例如写一个打印hello的函数,如下

def hello():               
    print('hello')

if __name__=='__main__':    
    hello()   

       输出结果如下:

 

       如果我们要修改函数内容,对函数进行监控,可以直接修改代码。但往往由于工作量很大,不可能一个一个改。所以要将其独立出来进行拓展。在Java里面称为注解,在Python中称为装饰器。

       装饰器就是给原来的函数加了一个包装(wrapper),利用包装对原函数进行修改与装饰,从而达到拓展功能的目的。

       在这里我们增加一个简单的装饰器:

def log(func):       #装饰器核心
    def wrapper():   #定义具体装饰过程
        print('before calling', func.__name__)
        func()
        print('end calling', func.__name__)
    return wrapper

@log                       
def hello():               #增加装饰器,func相当于一个函数指针
    print('hello')

if __name__=='__main__':    #主函数
    hello()                 #相当于调用log(hello())

       其输出结果如下:

 

       如果带参数怎么办呢?带参数可以如下处理

def log(func):       #装饰器核心
    def wrapper(name):   #定义具体装饰过程
        print('before calling', func.__name__)
        func(name)
        print('end calling', func.__name__)
    return wrapper

@log                       
def hello(name):               
    print('hello',name)

if __name__=='__main__':    #主函数
    hello('CSDN')

       输出结果如下

 

       因为参数有很多,所以我们也可以用Python中的通用参数表示。

       一个*表示无名字参数,两个**表示有名字参数,即:

       *args:无名字参数

       **kvargs:有名字参数(有名字无名字就是有没有参数名)

       代码就可以改写为如下,增加年龄:

def log(func):       #装饰器核心
    def wrapper(*args,**kvargs):   #定义具体装饰过程
        '''
        #args为无名字参数
        ##kvargs为有名字参数
        '''
        print('before calling', func.__name__)
        print('args:',args,'kvargs:',kvargs)
        func(*args,**kvargs)
        print('end calling', func.__name__)
    return wrapper

@log                       
def hello(name,age):            
    print('hello',name,age)

if __name__=='__main__':    #主函数
    #hello('CSDN',2)
    hello(name='CSDN',age=2)

       运行结果如下:

 

       我们发现kvargs为空。说明CSDN和2都是无名字的变量,如果将

  
hello('CSDN',2)

       改为

hello(name='CSDN',age=2)

       再次打印结果如下:

 

       这个时候CSDN和2就变成了有名字的变量。

       再进阶一下,在写装饰器的时候log(可以定义其他的)是分等级的,也就是说其可以带参数,这个时候代码思想都是一致的,就是再在装饰器内加一层即可。

def log(level,*args,**kvargs):     #装饰器核心
    def inner(func):                     #嵌套两层
        def wrapper(*args,**kvargs):   #定义具体装饰过程
            print(level,'before calling', func.__name__)
            print(level,'args:',args,'kvargs:',kvargs)
            func(*args,**kvargs)
            print(level,'end calling', func.__name__)
        return wrapper
    return inner

@log(level='INFO')                      
def hello(name,age):              
    print('hello',name,age)

if __name__=='__main__':    #主函数
    #hello('CSDN',2)
    hello(name='CSDN',age=2)

       结果如下:

 

       唠唠叨叨说了一点,最后提炼一下,装饰器大体思路如下:

def myDecorator(...):    #定义装饰器,可能带参数
    def decorator(func):    #装饰器核心,以被装饰的函数对象为参数,返回装饰后的函数对象
        def wrapper(*args, **kvargs):    #装饰的过程,参数列表适应不同参数的函数
            ...    #修改函数调用前的行为
            func(*args, **kvargs)    #调用函数
            ...    #修改函数调用后的行为
        return wrapper
    return decorator

@myDecorator(...):    
def myFunc(...):      #给函数加上装饰器,自己定义的功能函数

if __name__=='__main__':  #主函数

       欢迎交流!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python函数装饰器是一种特殊类型的函数,它可以用来修改其他函数的功能。装饰器可以在不修改被装饰函数源代码的情况下,为其添加额外的功能。装饰器本质上是一个返回函数函数,它使用了闭包的概念。 Python提供了@符号作为装饰器的语法糖,使得应用装饰器更加方便。使用装饰器时,可以直接在被装饰函数的定义上方使用@符号加上装饰器函数的名称,就可以将被装饰函数作为参数传递给装饰器函数进行处理。 函数装饰器的应用场景很广泛,它可以用于添加日志记录、性能分析、权限验证、缓存等功能。通过使用装饰器,我们可以将这些功能从原始函数中分离出来,提高代码的可读性和可维护性。 以下是一个简单的示例,演示了如何使用函数装饰器: ``` def decorator(func): def wrapper(*args, **kwargs): # 添加额外的功能 print("装饰器添加的功能") # 调用原始函数 return func(*args, **kwargs) return wrapper @decorator def my_function(): print("原始函数") my_function() ``` 在上面的例子中,我们定义了一个装饰器函数`decorator`,它接受一个函数作为参数,并返回一个新的函数`wrapper`。在`wrapper`函数中,我们可以添加额外的功能,并调用原始函数。通过使用`@decorator`语法,我们将`my_function`函数传递给装饰器进行处理。 当我们调用`my_function()`时,实际上调用的是装饰器返回的`wrapper`函数。在执行`wrapper`函数之前,会先执行装饰器添加的额外功能,然后再调用原始函数。 这就是Python函数装饰器的基本原理和用法。通过使用装饰器,我们可以轻松地修改函数的功能,使代码更加简洁和可重用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值