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

1 写在前面

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

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

2 小例子

这是一个装饰器:

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

使用call_print装饰器:

@call_print
def myfun():
  pass
 
@call_print
def myfun2():
  pass

myfun()后返回:

In [27]: myfun()
you're calling myfun function

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

3 使用call_print

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

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

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

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

4 装饰器本质

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

def myfun():
  pass

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

下面是最重要的代码:

myfun = call_print(myfun)
myfun2 = call_print(myfun2)

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

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

In [32]: myfun()
you're calling myfun function

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

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

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


近期小例子:pyecharts绘制词云图使用pillow处理图片,很简单!slice对象的应用举例一行代码优化异常输出函数的五类参数使用例子绘制时间线轮播图python参数类型使用总结绘制水球图lambda参数之坑Python绘制仪表盘参数的默认值陷阱!;chain串联多个迭代对象机器学习中会涉及到的随机选择样本使用namedtuple的小例子pkuseg 做分词,超级nice~写一个装饰器:统计异常发生次数和时间;对象可被调用的实现方法;求任意维度两点间距离两种合并字典的方法对比计算和聚合同时进行groupby 分组plotly画柱状图+折线图;

有收获,点个在看;想要了解更多小例子,点击阅读原文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!装饰是Python语言中的一个特性,它可以用来修改函数或类的行为。简而言之,装饰就是一个用来装饰其他函数或类的函数。 装饰的作用是在不修改被装饰对象源代码的情况下,给它添加额外的功能或行为。它可以让我们在代码中添加一些通用的功能,比如日志记录、性能分析、缓存等,而不需要在每个函数或类中都重复写相同的代码。 具体来说,装饰是一个函数,它接受一个函数(或类)作为输入,并返回一个新的函数(或类)。这个新函数通常会在原函数的基础上做一些额外的操作,然后返回结果。 举个例子,假设我们有一个函数 `say_hello`,我们希望在每次调用这个函数时打印一条日志。我们可以定义一个装饰函数 `log_decorator` 来实现这个功能: ```python def log_decorator(func): def wrapper(*args, **kwargs): print("Calling function: ", func.__name__) return func(*args, **kwargs) return wrapper @log_decorator def say_hello(): print("Hello, world!") say_hello() # 执行 say_hello 函数,并自动打印日志 ``` 在上面的例子中,`log_decorator` 装饰定义了一个名为 `wrapper` 的新函数,它在调用被装饰的函数之前先打印一条日志,然后再调用原函数。最后,`log_decorator` 装饰返回了这个新函数 `wrapper`。 通过在 `say_hello` 函数上使用 `@log_decorator`,我们将 `say_hello` 函数传递给了 `log_decorator` 装饰,并创建了一个新的函数。当我们调用 `say_hello` 函数时,实际上是在调用被装饰后的 `wrapper` 函数,它会先打印日志,然后再执行原来的 `say_hello` 函数。 这就是装饰的基本概念和用法。它可以帮助我们将代码中的一些通用功能抽象出来,并可以轻松地应用到多个函数或类上,提高代码的复用性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值