对装饰器的理解

关于python装饰器的思考:

我们首先应该对函数进一步了解
函数也可以被传递,比如:

def a():
	print("a")
v = a
v()
输出结果为a  

这里我并没有加()即v = a(),因为v()此时将返回TypeError,而print(v)则由于无返回值而返回None


而v = a则将函数名作为参数传递,想要运行该函数只需要v(),此时print(v)将返回v的地址。 函数内也可以声明函数,但是此函数并不能在函数外访问,如:

如:

def a():
	def v():
		print('00')
	v()
v()
此时运行结果为00
							NameError: name 'v' is not defined  

函数也是可以被返回的

如果要返回函数,只需返回其函数名即可,其函数名将作为参数传递。如需调用则只需函数名加括号,在这里尤其要弄清楚传递和返回函数时该不该加括号。

如:

def a(x):
	def b():
		print('dyf')
	def c():
		print('abc')
	if x == '1':
		return b
	else:
		return c
x = input('请输入')
v = a(x)
v()
则输出结果为:
	请输入 1
	dyf
	请输入 2
	abc  

注: 如果想打印函数返回值一定要用输出函数,如果print(v())输出其返回值。 如果print(v)则输出其地址

函数内也可以定义函数,这种函数称之为内嵌函数,内嵌函数是私密的,因此不可在函数外调用,我们往 往将其作为返回值而进行调用。

return 可以返回多个值,其值可以被传递,但是应当注意,尽量不要用golbal返回值,涂添烦恼


对于装饰器而言,实际上是一个函数,只不过其参数也是个函数。应当注意的是传递函数时应使用其函数名而不加括号,其函数名将作为参数而传递。

语法有如下两种:

1.def a(f):
	def lmt():
		print('abc')
		f()
	return abc
def dyf():
	print('dyf')

dyf()
dyf = a(dyf)
dyf()
print(dyf.__name__)
输出结果为
					dyf
					abc
					dyf
					abc      #dyf函数的名和注释文档被重写(docstring)  
=============================================================================  
2.def a(f):
	@wraps(f)  @这个函数保留原函数名
	def lmt():
		print('abc')
		f()
	return abc
@a
def dyf():
	print('dyf')
dyf()	
输出结果为:
				abc
				dyf  

以上两种方式效果完全相同,只是@方式是其简便写法,装饰器的本质即: 以函数调用函数的方式来对被调用函数进行修饰,但要注意 在函数调用的过程中应当以函数名作为参数 在执行函数时才加括号。

若要保留被装饰函数的真是名需要调用functools模块的wraps()函数,语法为 @wraps(f),实际上wraps()函数本身就是一个装饰器,只不过其参数是一个函数罢了。

Ps.这是我对装饰器的简单初步理解,以后会进一步补充。