消除装饰器对原函数的属性影响

 


 

首先介绍Python的"万能"装饰器模版:

import os
def decor(func):
    def with_decor(*args, **kwargs):  #这里内部嵌套函数使原函数参数能顺利传递
        func(*args, **kwargs)  #func_A 会在这里被调用
        a = args
        print(a)
    print('call decor')
    return with_decor

@decor
def func_A(*args, **kwargs):
    print('call A')
    
func_A(1,2,3)
os.system("pause")

  该程序将会输出:

  

  调用 func_A 函数会执行直接装饰器里的内容,并将参数传入闭包


 然后介绍一下这种一般装饰器的副作用:

   python装饰器会使原函数的属性被改变,比如func.__name__

  这里添加一行 print(func_A.__name__) 来展示影响

  输出效果:

 

 

   可以看到原函数 func_A 的名字变成了装饰器里面的函数 with_decor 的名字

  这导致一些特殊场合要用到这些属性时不方便,比如在 Robot Framework 自动化测试框架中调用函数,函数被装饰后就不能被正常调用


 因此可采用from functools import wraps,避免这种影响:

import os
from functools import wraps
def decor(func):
    @wraps(func)
    def with_decor(*args, **kwargs):
        return func(*args, **kwargs)
    return with_decor

@decor
def func_A(*args, **kwargs):
    print('call A')
    
func_A(1,2,3)
print(func_A.__name__)
os.system("pause")

  输出:  可以看到原函数的属性没有被改变

 

   wraps 的作用可以理解为消除装饰器的影响

posted @ 2020-12-28 22:45  Pio-GD  阅读(151)  评论(0)    收藏  举报