2、@操作符

@符号用于修饰函数,该修饰符后面接一个函数名后,在第下一行再接一个函数定义,这个函数定义可以是模块或类方法,不允许修饰类。修饰符@加一个函数名相当于该函数,同时将后面修饰的函数作为参数传递,需要返回一个可以调用的函数,并且这个返回的函数与修饰的函数名同名。下面通过几个实例进行解释:

实例1:


def decorator(decorated_function):
     print("hello, wang shuo")
 @decorator
 def decorated_funciton(a,b):
     print(a+b)


输出:

hello, wang shuo
修饰函数在定义时就会执行,因为前面说道@后面的函数会将修饰的函数decorated_function作为参数,同时返回一个可以调用的函数,这个返回的函数与修饰的函数同名。所以在定义时就要执行,因为需要返回一个可调用的函数。所以,在定义时执行了print("hello, wang shuo"),但是,由于没有返回可以调用的东西,所以通过@修饰后就没有可以调用的东西,调用decorated_function(a,b)是不行的,因为通过@修饰后它代表的是decorator返回的内容,由于没有返回,也就无法调用,所以这种情况调用decorated_function(3,4)会报错。TypeError: 'NoneType' object is not callable

实例2:
def decorator(decorated_function):
     print("hello, wang shuo first time")
     def actual_function(*args):
         print("hello,wang shuo second time")
     return actual_function
 @decorator
 def decorated_function(a,b):
     print(a+b) 
 print("meet wang shuo")
 decorated_function(2,3)输出:
hello, wang shuo first time
 meet wang shuo
 hello,wang shuo second time



这里首先输出了“hello, wang shuo first time”,说明在执行print之前就执行了decorator函数中的内容,该函数返回一个可以调用的内容,即actual_function,于是,被@修饰过的函数就变成了这个actual_fuction,于是在调用decorated_function(2,3)时依然输出“hello,wang shuo second time”,即actual_function中的内容。

实例3:

def decorator(dec_fun):
     print("hello, wang shuo first time")
     def actual_function(*args):
         print("hello,wang shuo second time")
         dec_fun(*args)
     return actual_function
 @decorator
 def decorated_function(a,b):
     print(a+b) 
 print("meet wang shuo")
 decorated_function(2,3)

输出:

hello, wang shuo first time
meet wang shuo
hello,wang shuo second time
5
可以看到这次输出了a+b的内容,这是因为在actual_function中调用的被修饰的函数,因为被修饰的函数作为参数传递给函数decorator,而在返回的函数中调用了这个函数dec_fun(*args),所以在使用decorated_function过程中也会使用该函数的功能。

总结:


通过@修饰的函数能够执行那些内容不是看被修饰函数的内容,而是需要看用来修饰的函数的内容,即decorator,它的返回可调用的内容才是最终的执行函数,在调用这个被修饰的函数(decorated_function)时,就会调用decortor返回的可调用的部分。