Python中的@函数装饰器到底是什么?

在解释@函数装饰器之前,先说一下,类中的类方法和静态方法。

在Python中完全支持定义类方法、静态方法。这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以)。

区别在于:Python会自动绑定类方法的第一个参数,类方法的第一个参数会自动绑定到类本身;但对于静态方法则不会自动绑定。

类方法用@classmethod修饰,静态方法用@staticmethod修饰,如下:

 1 #coding=utf-8
 2 class Person:
 3     @classmethod
 4     def eat(cls):
 5         print("类方法eat:",cls)
 6         
 7     @staticmethod
 8     def sleep(p):
 9         print("静态方法sleep:",p)
10 
11 
12 Person.eat()
13 Person.sleep("info")
14 
15 p = Person()
16 
17 p.eat()
18 p.sleep('info')

控制台打印如下:

解释:eat方法因为是@classmethod修饰所以它是类方法,所以第12行调用时,不用传入任何参数,即可以调用,因为它会自动绑定类本身到第一个参数。

sleep方法因为是@staticmethod修饰所以它是静态方法,所以在第13行调用时,需要传入参数。再看17、18行,可以得出结论:不管是用类或者对象调用静态方法,Python都不会对静态方法的第一个参数进行自动绑定。

  上面的@classmethod 和 @staticmethod 其实就是函数装饰器,其中classmethod和staticmethod为Python中内置的函数。

  使用@符号引用已有函数后,可用于修饰其他函数。

例如@函数A 装饰 函数B ,实际完成的步骤为:

1.将被装饰的函数B作为参数传给函数A

2.将函数B替换为第1步的返回值。

举个例子:

 1 def funA(fn):
 2     """参数为一个函数对象"""
 3     print('A')
 4     fn() #执行传入的fn函数
 5     return 'tizer'
 6     
 7 '''
 8 下面的代码相当于funA(funB)
 9 funB将会被替换为该语句的返回值
10 由于funA返回tizer,因此funB就是tizer
11 '''
12 @funA
13 def funB():
14     print('B')
15 print(funB)

先看运行结果:

解释:既然funB作为参数传给了funA,那就是得先执行funA中的代码,所以执行了print(‘A’),打印了A,然后执行第4行fn(),因为传入的funB,funB中的代码为print('B'),所以打印了B,然后funA 返回了一个字符串tizer,所以funB 等同于 tizer,第15行print(funB) 等同于 print('tizer'),所以打印了tizer。

  

原文地址:https://www.cnblogs.com/tizer/p/11128832.html