• 31-高级特性之装饰器(1)


    1. 定义:

    Decorator(即装饰器)其实就是闭包实现的一个函数:把{一个待扩展功能的函数Fun}当做参数传入一个外函数Out,在外函数内部定义的内函数In“装饰扩充”Fun,然后返回In。

    • 一句话描述:把一个函数A当参数传入另一个函数B,并返回一个函数C

      def Out(Func):
      def In(args, **kw): #这两个参数其实是给Func()使用的
      print("前置修饰操作 ")
      Func(
      args, **kw) #当前置修饰操作一旦完成,就自动执行Func
      print("后置修饰操作 ")
      return In #把闭包返回出去

      现在一旦执行Out,就会得到In,再执行In(),就会立刻执行前置修饰操作,接下来得到Func()的执行结果并返回出去

      装饰器Out的效果就是:先执行前置操作,再执行Fun(),再执行后置方法

      不用语法糖,先手动模拟下装饰器的运行:

      def fun_1():
      print("I am fun_1 ")
      ret = Out(fun_1) #得到In
      ret() #执行In

      使用语法糖

      @Out #加装饰器Out
      def fun_2():
      print("I am fun_2 ")
      fun_2()

      其实 @Out 等价于 ret = Out(fun_2), fun_2()等价于 ret()

    • Decorator的效果:

    • 遵循“开放封闭原则”:对扩展开放,对已写好的函数封闭
    • 一个装饰器写好了,可到处重用
    • Decorator的应用:
      假设有A函数已经写好了,想为它扩充如下功能:
    1. 引入日志
    2. 函数执行时间统计
    3. 执行函数前预备处理
    4. 执行函数后清理功能
    5. 权限校验等场景
    6. 缓存

    实例:

    • 实例1:

      定义Decorator

      def makeBold(func):
      def wrapper():
      return ''+func()+'' #给文本加粗
      return wrapper

      def makeItalic(func):
      def wrapper():
      return ''+func()+'' #把文本设为斜体
      return wrapper

      装饰过程

      @makeBold
      def test1():
      return "I am test1!"

      @makeItalic
      def test2():
      return "I am test2!"

      @makeBold
      @makeItalic
      def test3():
      return "I am test3!"

      调用函数: 要根据装饰器里面对func()的修饰行为 {设置是否需要接受返回值的操作}

      此处需要接受返回值

      r1, r2, r3 = test1(), test2(), test3()
      print(r1, ' ', r2, ' ', r3)

    • func()即可能是无形参,也可能是带各种参数。为了兼容两种情况,采用func(*args, **kw)的方式处理:
    • func()即可能是有返回值,也可能是无返回值。为了兼容两种情况,采用 ret=func(), return ret的方式处理(因为如果函数没有返回值python默认都会return None)
    • 为了处理以上“参数和返回值问题”,可编写一个通用装饰器

      from time import ctime,sleep

      def timefun(func):
      def wrapper(args, **kw): #支持可变参数,关键字参数 {实现了对参数的自适应}
      print("%s called at %s" % (func.name, ctime()))
      ret = func(
      args, **kw) #若有返回值,接受并待会儿返回;若无,返回None
      #...若干操作后
      return ret #实现了对返回值的自适应
      return wrapper

      @timefun
      def test1(): #无参
      print("-----test1----")
      test1()
      sleep(1)
      test1()
      print(' ')

      @timefun
      def test2(a,b): #有参数
      print("%s %s" % (a,b))
      test2(10,20)
      sleep(1)
      test2(20,30)
      print(' ')

      @timefun
      def test3(a,b): #无返回值
      print("%s+%s=%s" % (a,b,a+b))
      ret = test3(100,200)
      sleep(1)
      ret = test3(200,300)
      print(ret, ' ')

      @timefun
      def test4(a,b): #有返回值
      return a -b
      ret = test4(1000,2000)
      print(ret)
      sleep(1)
      ret = test4(2000,3000)
      print(ret, ' ')

  • 相关阅读:
    PAT乙级1008. 数组元素循环右移问题 (20)
    PAT乙级1007. 素数对猜想 (20)
    PAT乙级1006. 换个格式输出整数 (15)
    ubuntu mate 开机自动启动ssh服务
    ubuntu 修改网卡名称
    ubuntu 绑定固定ip
    ubuntu sogou 輸入法無法輸入文字,解決辦法【转载】
    select()函数小结【转载】
    listen函数小结
    python学习过程二(《python核心编程》第三章)
  • 原文地址:https://www.cnblogs.com/LS1314/p/8504542.html
Copyright © 2020-2023  润新知