装饰器进阶

Posted zxmbky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器进阶相关的知识,希望对你有一定的参考价值。

  • 函数的有用信息
    • 如何给函数添加注释
    • def func(*args,**kwargs):
          """
           这里是函数的注释,先写?下当前这个函数是?什么的
          :param args:参数args是什么意思
          :param kwargs:参数kwargs是什么意思
          :return:返回值是什么
          """
          print("哈哈")

       

    • 如何获取到函数的相关信息
    •   
      def func(*args,**kwargs):
          """
           这里是函数的注释,先写?下当前这个函数是?什么的
          :param args:参数args是什么意思
          :param kwargs:参数kwargs是什么意思
          :return:返回值是什么
          """
          print("哈哈")
      print(func.__name__) #获取函数的名字
      print(func.__doc__)  #获取函数的注释
      • 函数名._name_可以查看函数的名字
      • 函数名._doc_可以查看函数的文档注释
    • 被装饰器装饰之后的函数名
    • def wrapper(func):
          def inner(*args, **kwargs):
              ret = func(*args, **kwargs)
              return ret
          return inner
      # @wrapper 相当于target_func=wrapper(target_func)语法糖
      @wrapper
      def target_func():
          print("我是?标函数")
      # 调?目标函数 
      target_func() 
      print(target_func.__name__)     # inner 结果: inner 
    • 我虽然访问的是target_func函数,但是实际执行的是inner函数.这样就会给下游的程序带来困惑.我们需要修改函数信息.
    • from functools import wraps # 引?入函数模块
      #  装饰器:对传递进来的函数进?包装.可以在?
      def wrapper(func):
          @wraps(func)    # 使?函数原来的名字
          def inner(*args, **kwargs):
              ret = func(*args, **kwargs)
              return ret
          return inner #
      # @wrapper 相当于target_func=wrapper(target_func)语法糖
      @wrapper
      def target_func():
          print("我是?标函数") # 调??标函数
      target_func()
      print(target_func.__name__)     # 不再是inner.?是target_func了
    • *args和**kwargs
      • 接受参数的时候是聚合,参数声明
      • 传递参数的时候是打散,给函数传递实参
  • 装饰器传参
  • def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print(‘‘‘执行函数之前要做的‘‘‘)
                re = func(*args,**kwargs)
                if flag:
                    print(‘‘‘执行函数之后要做的‘‘‘)
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()
    
    带参数的装饰器
  •  执行步骤: 先执行outer(False) 然后再@返回值.   返回值恰好是timer. 结果就是 @timer
  • 多个装饰器装饰同一个参数
  • def wrapper1(func):
        def inner():
            print(wrapper1 ,before func)
            func()
            print(wrapper1 ,after func)
        return inner
    
    def wrapper2(func):
        def inner():
            print(wrapper2 ,before func)
            func()
            print(wrapper2 ,after func)
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print(in f)
    
    f()
    
    多个装饰器装饰同一个函数
  • 执行顺序:首先@wrapper1装饰起来. 然后获取到一个新函数是wrapper1中的inner. 然后执行@wrapper2.这个时候. wrapper2装饰的就是wrapper1中的inner了.
  • 所以. 执行顺序就像:
  •     第二层装饰器前(第一层装饰器前(目标)第一层装饰器后)第二层装饰器后.
  •  程序从左到右执行起来. 就是我们看到的结果

以上是关于装饰器进阶的主要内容,如果未能解决你的问题,请参考以下文章

12.前方高能-装饰器进阶

python使用上下文对代码片段进行计时,非装饰器

基础学习之第十二天(装饰器的进阶)

函数进阶(装饰器)

Python进阶第九篇装饰器

测开之函数进阶篇・第七篇《装饰器》