前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我对装饰器的一些通俗理解,或许能帮助到你~

我对装饰器的一些通俗理解,或许能帮助到你~

作者头像
double
发布2020-02-12 16:12:15
5040
发布2020-02-12 16:12:15
举报
文章被收录于专栏:算法channel算法channel

1 写在前面

python中使用@放在函数上方便定义一个装饰器,很多朋友觉得使用装饰器太魔幻,始终不知道怎么灵活使用。

要想做到灵活使用,得首先明白它的本质。今天,我试着用最通俗的语言,几行代码和小例子来解释装饰器的本质

2 小例子

这是一个装饰器:

代码语言:javascript
复制
def call_print(f):
  def g():
    print('you\'re calling %s function'%(f.__name__,))
  return g

使用call_print装饰器:

代码语言:javascript
复制
@call_print
def myfun():
  pass
 
@call_print
def myfun2():
  pass

myfun()后返回:

代码语言:javascript
复制
In [27]: myfun()
you're calling myfun function

In [28]: myfun2()
you're calling myfun2 function

3 使用call_print

你看,@call_print放置在任何一个新定义的函数上面,都会默认输出一行,你正在调用这个函数的名。

这是为什么呢?注意观察新定义的call_print函数(加上@后便是装饰器):

代码语言:javascript
复制
def call_print(f):
  def g():
    print('you\'re calling %s function'%(f.__name__,))
  return g

它必须接受一个函数f,然后返回另外一个函数g.

4 装饰器本质

本质上,它与下面的调用方式效果是等效的:

代码语言:javascript
复制
def myfun():
  pass

def myfun2():
  pass
  
def call_print(f):
  def g():
    print('you\'re calling %s function'%(f.__name__,))
  return g

下面是最重要的代码:

代码语言:javascript
复制
myfun = call_print(myfun)
myfun2 = call_print(myfun2)

大家看明白吗?也就是call_print(myfun)后不是返回一个函数吗,然后再赋值给myfun.

再次调用myfun, myfun2时,效果是这样的:

代码语言:javascript
复制
In [32]: myfun()
you're calling myfun function

In [33]: myfun2()
you're calling myfun2 function

你看,这与装饰器的实现效果是一模一样的。装饰器的写法可能更加直观些,所以不用显示的这样赋值:myfun = call_print(myfun)myfun2 = call_print(myfun2),但是装饰器的这种封装,猛一看,有些不好理解。

怎么样,相信你会有一些收获,恭喜你!这是我的原创,如果可以,帮我分享一下吧。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员郭震zhenguo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档