python函数装饰器和类装饰去的区别和相同点

python函数装饰器和类装饰去的区别和相同点

函数装饰器

# 定义一个函数装饰器
def other(func):	# 3
    def inner(*args, **kwargs):	# 5
        print("我是一个装饰器")	# 6
        return func(*args, **kwargs)	#7
    return indder	# 4


@other	# 2
def index(a, b):	# 8
    print(a+b)

index(2, 3)	# 1
# 这个执行结果是
'''
我是一个装饰器
5
'''
  • 我来看一下这个装饰器是怎么运行的吧:

    • 首先,@other就相当于a = other(index)这样的一个形式,把它要装饰的一个函数当成参数传递给了other(func),这个时候,func代表的就是index的整个函数,然后呢,我们可以看到,这个装饰器里面还有一个函数,但是在第一遍执行的时候内函数因为没有被调用,所以不会执行,当碰到外函数的return时,就是说外函数返回了内函数,现在就开始执行内函数了,开始打印"我是一个装饰器"这句话,然后,内函数返回了外函数的引用,之前说过,现在的func相当于是一个index的函数,所以,调用了index(a, b)这个函数,把(2, 3)的值放了进去,运算得5,装饰器的大概流就是这样的
    • 上面的数字就是执行的过程
  • 那什么是类装饰器呢?我们先来看看代码吧:

    # 定义一个类,做装饰器
    class Other:
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args, **kwargs):
            print("我是一个装饰器")
            self.func(*args, **kwargs)
    
    # def __call__(self, *args, **kwargs):这个一个类里面的内置方法,当实例化一个
    类时成为对象时,类的对象被调用时,自动执行这个方法,不是平时的那种对象.属性这样的用法.....
    @Other
    def box(a, b):
        print(a + b)
        
    box(2, 3)
    
  • 如果函数形式的装饰器理解了,那么理解类的装饰器应该很容易的,来,我们一起来看看吧.首先,装饰器的本质就是把你装饰的函数当成一个参数传递,对比一下函数类型的装饰器,我们知道,@Other的作用是相当于是实例化一个类,形如a = Other(box)这样的,当然,这个时候的box 被当成参数传给了类中的func,我们知道,平时我都是用这个实例出来的a去点什么东西,获取类的属性,方法什么的,但是,现在这个a被当成了一个对象直接调用了,所以,它回去找到def __call__(self, *args, **kwargs):这个方法,这个相当与是函数类型中的return,然后开始按照流程打印了,两个运行的结果是一样的

扩展(这个我就不讲了)

  • 可以传参的装饰器
# 函数类型的
def foo(name):
    def other(func):
        def indder(*args, **kwargs):
            print("这个是一个---" + name)
            print("我是一个装饰器")
            return func(*args, **kwargs)
        return indder
    return other


@foo('laowang')
def index(a, b):
    print(a + b)


index(2, 3)
# 结果
'''
这个是一个---laowang
我是一个装饰器
5
'''
# 类类型的
class Foo:
    def __init__(self, name):
        self.name = name

    def __call__(self, func):
        self.func = func
        return self.inner

    def inner(self, *args, **kwargs):
        print(self.name)
        self.func(*args, **kwargs)


@Foo('laowang')
def box(a, b):
    print(a + b)


box(2, 3)
# 结果
'''
laowang
5
'''

你可能感兴趣的:(python)