上海装饰工程物联网现全面招商,热烈欢迎!0510-88602202
标王 热搜:
 
 
当前位置: 首页 » 公告中心 » 行业趋势
哪有那么复杂?类装饰器,一个小例子就彻底懂了
 [打印]添加时间:2022-03-18   有效期:不限 至 不限   浏览次数:2619
   先简单说一下什么是装饰器。
 
  装饰器,顾名思义,就是起装饰作用的东西。手机壳是一种装饰品。手机膜也是一种装饰品。
 
  在编程的世界里,装饰器的作用,就是用一个壳子把一个函数包起来。以后每次调用的时候,实际上调用的是这个壳子。这个壳子先做一些操作,然后壳子再调用真正的函数。
 
  装饰器可以是一个函数,也可以是一个类。今天就聊一下类装饰器。
 
  类装饰器
 
  昨天我们举了一个类装饰器的例子。我把它稍微改造了一下:
 
  有一个函数cook(),也就是做饭。不是苹果CEO那个库克,是做饭的厨师。
 
  我们希望每次做饭之前,都要先洗手。
 
  这里的WashHandDecorator就是一个类装饰器。
 
  我们通过@WashHandDecorator声明了用这个装饰器来装饰cook()函数
 
  打印结果:
 
  洗手装饰器组装中...先洗手,再做饭...做饭中...美味香喷喷...但是自己不能吃...先洗手,再做饭...做饭中...美味香喷喷...但是自己不能吃...先洗手,再做饭...做饭中...美味香喷喷...但是自己不能吃...
 
  原理解释
 
  上面的原理已经解释了一半了,还不够透彻。所以继续:
 
  WashHandDecorator是装饰器。
 
  它装饰了函数cook()以后,以后每次调用cook(),实际上是调用的WashHandDecorator类的实例,也就是调用了__call__函数,这个函数会再调用cook()。也就是先洗手,洗完手再去做饭。
 
  其实装饰器的语法,也就是那个@WashHandDecorator,只是一个语法糖衣。不用这个语法,我们也可以实现同样的效果:
 
  这个的执行结果和上面是完全一样的。
 
  来看最关键的这一行cook=WashHandDecorator(cook):
 
  参数中的cook代表的是上面定义的cook()函数,它作为参数传给了WashHandDecorator的构造函数。
 
  而前面的变量名cook是新构造出来的WashHandDecorator的实例,只是故意让它的名字和函数名相同。
 
  这样后面再调用cook()的时候,实际上不是调用的cook()函数,而是调用的这个对象实例。
 
  对象一般不可以直接这样cook()调用的,除非它有__call__函数,而WashHandDecorator正好有这个函数。
 
  __call__函数里实现了:先洗手,然后再调用原本的cook()函数。
 
  这就是整个装饰的过程。使用装饰器的语法不过是自动帮我们实现了上面的过程。
 
  所以一个类要成为装饰的,最重要的就是必须有__call__函数,这就和上一个三分钟呼应上了。