在定义修饰器的时候,可能会遇到上面这种报错
def A(func):
def B():
print('哈哈,我来啦')
func()
print('哈哈,我走啦')
return B()
@A
def C():
print('我是C')
C()
解决办法很简单,以上面的代码为例,只需要将“return B()”中的()删除就可以,改成
def A(func):
def B():
print('哈哈,我来啦')
func()
print('哈哈,我走啦')
return B
@A
def C():
print('我是C')
C()
因为,return其实是要将函数B返回给C。
就是,当程序运行到“@A”这一行的时候,程序会自动将函数C传入函数A当中,并且自动运行,运行之后的结果会储存在函数B的内存空间里,然后return B可以返回函数B可以使C = B,也就是再调用函数C,运行的其实是传入了C后B的代码,而不是运行最开始C的代码。
而如果是return B()的话,返回的是函数B运行之后的结果,使得函数C不再是一个函数,而是等于B运行之后的结果,所以会报TypeError的错误,因为这个时候C不再是一个函数,所以不可以被调用。
网上还有另外一种说法,说在调用函数C的时候,把C后面的括号删除就行
def A(func):
def B():
print('哈哈,我来啦')
func()
print('哈哈,我走啦')
return B()
@A
def C():
print('我是C')
C
就像上面这个代码一样,直接把最后一行调用函数C的括号删除,然后运行,发现没有错误,可是这其实是错误的做法,因为可以运行下面这个代码
def A(func):
def B():
print('哈哈,我来啦')
func()
print('哈哈,我走啦')
return B()
@A
def C():
print('我是C')
然后就会发现运行的结果和前面两次都一样,可是我们明明没有调用函数C呀?
因为,我们前面那句“return B()”返回了函数B的调用结果给了函数C,而因为这个函数B里面有两句print,所以在返回函数B的结果的时候,程序会输出,也就是说当我们的处理方法为删除函数C后面的括号的时候,其实程序的输出是因为你把函数B的调用结果返回给C导致的。
那为什么返回函数B给C,程序就不会输出任何东西呢?
def A(func):
def B():
print('哈哈,我来啦')
func()
print('哈哈,我走啦')
return B
@A
def C():
print('我是C')
就像上面的代码一样,运行之后,程序不会输出任何东西,因为你返回函数B给C,其实是让C的IP地址指向B的IP地址这一过程,所以程序并不会输出任何内容。就像我们让一个变量x等于另一个变量y,其实是让x的IP地址指向y的IP地址。而如果我们让变量x等于2,其实是直接给变量x赋值,然后x的IP地址没有发生任何变化。