Python案例实操
函数装饰器
函数装饰器的广泛应用
- 前面讲的
@staticmethod
和@classmethod
的本质就是函数装饰器 staticmethod
和classmethod
都是python内置的函数,可以使用help(classmethod)
来查看它的作用:
help(classmethod)
Help on class classmethod in module builtins:
class classmethod(object)
| classmethod(function) -> method
|
| Convert a function to be a class method.
|
| A class method receives the class as implicit first argument,
| just like an instance method receives the instance.
| To declare a class method, use this idiom:
|
| class C:
| @classmethod
| def f(cls, arg1, arg2, ...):
| ...
- 可以看出,和我们前面学到的内容一致。
函数装饰器的本质
- 当程序使用
@函数
比如函数A装饰另一个函数,比如函数B时,实际上完成了如下两步:- 将被修饰的函数(函数B)作为参数传给@符号引用的函数A
- 将函数B替换(装饰)成第一步的返回值
# foo函数,该函数将作为函数装饰器使用
# 作为函数装饰器使用的函数,必须定义一个形参
def fun1(fn):
print("fun1函数")
print(fn)
return "lancibe"
# 被装饰的函数
@fun1
def fun2():
print("fun2函数")
'''
函数装饰器的本质:
(1)将被装饰的函数(fun2)作为参数传给装饰器函数(fun1)
(2)被装饰的函数(fun2)将被替换成装饰器函数(fun1)的返回值
'''
print(fun2) # fun2被装饰——被替换成装饰器的返回值
print(type(fun2))
- 上面程序的结果是
fun1函数
<function fun2 at 0x7fecd7a7d7b8>
lancibe
<class 'str'>
- 这和前面注释的内容一致,注意这时候
fun2
函数就不能再被调用了,如果写了fun2()
,系统会报错:TypeError: 'str' object is not callable
。一般情况下,装饰器函数的返回值不会是一个字符串,而是一个更有意义的东西,如下:
def fun1(fn):
print("fun1装饰器函数")
# fn就代表了被装饰的函数
def fun3(*a):
print("fun3函数")
fn(*a)
return fun3
# 被装饰的函数
# (1)fun2函数会被作为参数传给fun1装饰器函数、
# (2)fun2函数就会被替换成fun1装饰器函数的返回值(fun3)
@fun1
def fun2(a, b):
print("fun2函数")
print("参数a", a)
print("参数b", b)
# 表面上是调用fun2函数,实际上是调用了fun1装饰器函数的返回值(fun3)
fun2(2,4)
- 上面的程序的结果是:(注意不同行的先后顺序)
fun1装饰器函数
fun3函数
fun2函数
参数a 2
参数b 4
- 这一部分的逻辑关系比较乱,需要慢慢理解。