python_装饰器篇(一个装饰器充当有参和无参两种表达)

大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油!

今天看到一个有趣关于装饰器活用的一种表达,之前在使用装饰器的时候,我们很多时候都是有参数,无参数等进行区分,比如一个典型的装饰器函数有参数的情况

def log2(param):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            if not param:
                print('%s no param' % (param))
            else:
                print('%s in %s()' % (param, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return decorator

@log2("")
def now3():
    print("now3")

@log2("test")
def now4():
    print("now4")

如上代码可以看出就是一个普通装饰器方法带参数的例子,通过参数的判断来调整输出,结果如下:


image.png

那么如果我想实现一种如下图的装饰器显示方式,那个该怎么处理呢??

image.png

如图片所示,我想用一个装饰器方法名既能充当有参数的情况,也能充当无参数的情况
这是一个很好的方式, 废话就不说了,上代码

import functools

def log(param):
    # 不存在可调用对象的情况下
    if callable(param):
        def wrapper(*args, **kwargs):
            print('%s function()' % (param.__name__,))
            param(*args, **kwargs)
        return wrapper
    
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (param, func.__name__))
            return func(*args, **kw)

        return wrapper
    return decorator

如代码所示,通过callable来判断当前是否是可调用对象,如果是可调用对象则作为无参数来进行使用,如果不是一个可调用对象,则作为一个普通参数来处理


image.png

至于为什么是这个情况呢?
下面简单说一下自己的理解

我们应该知道作为一个装饰器他们再执行的时候,是具有一下特点的,为了方便找了一个截图


image.png

如图所示 一个 @log 等于 如下表达:

t = log(f1) 通过return wrapper返回执行对象
t()

通过这表达式来解读上面的实现原来就可以明白


image.png

通过判断当前的这个param是否是f1这个方法的对象,如果是方法的对象则理解为普通的@log装饰器,如果是这个param不是一个f1这个对象而是一个普通的“测试‘这个参数,那么就当作一个@log(”测试')来进行处理

这就是上面之所以可以实现合并表达的主要原因

当然这些都是自己的一种理解认知,如果有不合适的地方,也欢迎朋友指正,谢谢

你可能感兴趣的:(python_装饰器篇(一个装饰器充当有参和无参两种表达))