python 装饰器

1.闭包函数

首先了解闭包:在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。

实例如下:

def outer(x):
    def inner(y):
        return x+y
    return inner

print(outer(6)(5))

输出如下:

11

函数解释:定义一个函数outer,参数为:x,在outer函数内又定义了inner函数,引用外部的x参数,这就是闭包函数。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。

2.装饰器

  装饰器就是一个闭包函数,是闭包的一种应用。python装饰器是用于拓展原功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的喊出就是在不用更改原函数的代码前提下给函数增加新的功能。装饰器书写“@func”

def  debug(func):
    def wrapper():
        print("[DEBUG]:enter{}()".format(func.__name__))
        return func()
    return wrapper


@debug
def hello():
    print("hello")

hello()
输出:
[DEBUG]:enterhello()
hello

3.带参数的装饰器

def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]:enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper


@logging(level="INFO")
def hello(a,b,c):
    print(a, b,c)

hello("hello", "good", "morning")
------------------------------------
[INFO]:enter hello()
hello good morning

如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。

4.类装饰器

类装饰其用法与函数装饰器并没有太大区别,实质时使用了类方法中的call魔法来实现类的直接调用

class logging():
    def  __init__(self,func):
        self.func = func
    
    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)


@logging
def hello(a, b,c):
    print(a,b,c)

hello("hello", "good", "morning")
--------------------------------------------
[DEBUG]: enter hello()
hello good morning

带参数的类装饰器:

class logging():
    def __init__(self, level):
        self.level = level
    
    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        
        return wrapper


@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello", "good", "morning")
-------------------------------------------
[TEST]: enter hello()
hello good morning
不考虑业务场景,一味的争执技术的高下,都是耍流氓。
原文地址:https://www.cnblogs.com/leoych/p/14748809.html