Python案例实操——函数装饰器

Python案例实操

函数装饰器

函数装饰器的广泛应用

  • 前面讲的@staticmethod@classmethod的本质就是函数装饰器
  • staticmethodclassmethod都是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时,实际上完成了如下两步:
    1. 将被修饰的函数(函数B)作为参数传给@符号引用的函数A
    2. 将函数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
  • 这一部分的逻辑关系比较乱,需要慢慢理解。

你可能感兴趣的:(Python案例实操,python)