关于python装饰器的思考:

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

1
2
3
4
5
def a():
print("a")
v = a
v()
输出结果为:a

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


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

如:

1
2
3
4
5
6
7
def a():
def v():
print('00')
v()
v()
此时运行结果为:00
NameError: name 'v' is not defined

  • 进一步理解函

函数也是可以被返回的

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

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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.这是我对装饰器的简单初步理解,以后会进一步补充。