python-装饰器的使用

#修饰无参函数 ,无参数时不需要调用
def log1(func):
    func()
@log1
def test():
    print('test:')


#修饰有参函数
def log2(func):
    def inner(*args, **kwargs):
        func(*args, **kwargs)
    return inner
@log2
def test(num):
    print('testlog2:',num,test.__name__)
test(20) #相当于log(test(20))


from functools import wraps
#@wraps可以保证装饰器修饰的函数的name的值保持不变


#不带参数的装饰器
def log3(func):
    @wraps(func)
    def inner(*args, **kwargs,):
        func(*args, **kwargs)
    return inner
@log3
def test(num):
    print('testlog3:',num,test.__name__)
test(30) #相当于log(test(30))


#带参数的装饰器
def log4(level):
    def log(func):
        @wraps(func)
        def inner(*args, **kwargs,):
            if level == "warn":
                print("%s is running" % func.__name__)
            func(*args, **kwargs)
        return inner
    return log
@log4(level="warn")
def test(num):
    print('testlog4:', num, test.__name__)
test(40)



#实现带参数和不带参数的装饰器自适应
def log(arg):
    if callable(arg):  # 判断参入的参数是否是函数,不带参数的装饰器调用这个分支
        def log3(func):
            @wraps(func)
            def inner(*args, **kwargs, ):
                func(*args, **kwargs)
            return inner
        return log3
    else:
        def log4(func):
            @wraps(func)
            def inner(*args, **kwargs,):
                if arg == "warn":
                    print("%s is running" % func.__name__)
                func(*args, **kwargs)
            return inner
        return log4
@log(arg=None)
def test(num):
    print('testlog:', num, test.__name__)
test(0)




#返回入参出参
def log5(func):
    def inner(*args, **kwargs):
        print('入参:',func.__name__, args, kwargs)
        res =func(*args, **kwargs)
        print('出参:',func.__name__, res)
        return res
    return inner
@log5
def test(num):
    print('testlog5:', num, test.__name__)
    return num
print(test(50))



#类装饰器
class Loging:
    def __init__(self,level):
        self.level = level

    def __call__(self,func):
        @wraps(func)
        def inner(*args, **kwargs):
            if self.level == "warn":
                self.notify(func)
            func(*args, **kwargs)
        return inner

    def notify(self,func):
        print ("%s is running" % func.__name__)


@Loging(level="warn")
def test(num):
    print('testLoging:', num, test.__name__)
test(0)
原文地址:https://www.cnblogs.com/shuzf/p/13434477.html