Python装饰器为什么难理解:写个带参数的装饰器

题图:https://unsplash.com/@oldskool2016

哪些地方适合用装饰器呢?但凡是在多个地方出现雷同的代码块,且这些代码与核心业务没有直接关联的都可以用装饰器来代替,装饰器不仅能减少代码量,还使得代码逻辑更清晰、可读性更强,你只需专注于业务逻辑处理就行了。

今天说说带参数的装饰器,为了简化业务逻辑,只实现字符串大写转换的需求,重点来关注装饰器部分:

# 业务函数
def my_upper(text):
    value = text.upper()
    return value

print(my_upper("hello"))  # HELLO

现在需求有变更,核心业务不变,但是需要对转换的的字符包裹一层HTM标签,输出如: <p>HELLO</p>,最简单的办法就是直接在函数里面修改逻辑,如:

def my_upper(text):
    value = text.upper()
    return "<p>" + value + "</p>"

又接到产品通知,需求有变更,还要在外面套一个div,于是你很不情愿地回去再修改:

def my_upper(text):
    value = text.upper()
    return "<div><p>" + value + "</p></div>"

如何应对产品这种无止境的修改呢?

0?wx_fmt=gif

不过,技术最终还是要为业务服务,那我们就想一个可以灵活应对产品的办法吧,这里,装饰器就是一个很好的方案。最终效果应该是这样:

@tag("p")
def my_upper(text):
    value = text.upper()
    return value

print(my_upper("hello")) #<p>HELLO</p>

如何实现呢?先从简单装饰器开始,实现一个不带参数的装饰器

def tag(func):
    def wrapper(text):
        value = func(text)
        return "<p>" + value + "</p>"

    return wrapper

@tag
def my_upper(text):
    value = text.upper()
    return value

调用

print(my_upper("hello")) # <p>hello</p>

@tag 语法糖等价于  my_upper = tag(my_upper)

my_upper("hello") 等价于 wrapper("hello") 尽管你不能直接访问wrapper,但可以这样去理解

使用装饰器,业务代码一行的都没改,只需要在函数定义处加上装饰器,就实现了相同的功能,那么如何更灵活地通过参数来指定输出的样式呢?使用带参数的装饰器

带参数的装饰器

带参数的装饰器只需要在原来那个不带参数的装饰器基础上之上在最外层套一个函数,该函数中定义一个参数,然后嵌套函数中引用该参数即可实现。从下图看出,我只是把里面那个函数改了一下名字,其余和原来不带参数的装饰器是一样的。有没有觉得这样更灵活?

0?wx_fmt=png

当然,装饰器不仅可以修饰函数,还可以修饰类。

娱乐时间

最后留给大家一个问题,给函数实现一个日志记录功能,日志里面记录函数名,函数执行所花的时间,通过参数控制日志级别,最快写出且正确的读者可以找我(微信:lzjun567)领取10元红包。考虑代码在留言区显示不友好,统一使用 https://gist.github.com/ 托管代码段,然后直接留言代码链接就可以。如果你没法使用 github,可以找其它替代方案,总之代码格式看起来要规范。

关注「Python之禅」☟☟☟,提高Python技术

640?wx_fmt=jpeg

如果觉得文章不错,请帮忙转发朋友圈

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python装饰器是一种特殊的Python函数,它可以在不修改被装饰函数源代码的情况下,为被装饰函数添加额外的功能。装饰器本质上是一个闭包,它接收一个函数作为参数,并返回一个新的函数对象。这个新的函数对象包装了原始函数,并在其前后执行额外的代码。通过使用装饰器,我们可以在不改变原函数结构的情况下,扩展函数的功能,比如添加日志记录、性能计时、权限验证等功能。 装饰器的返回值也是一个函数对象,所以它可以像普通函数一样被调用装饰器可以用来装饰函数、方法或者类,使其拥有额外的功能。装饰器的语法是在被装饰函数定义的上方加上@符号,后面紧跟装饰器函数的名称。 装饰器可以分为函数装饰器和类装饰器两种类型。函数装饰器是最常见的一种形式,它是一个函数,接收一个函数作为参数,并返回一个新的函数对象。类装饰器是指以类的形式实现的装饰器,它必须实现`__call__`方法,并接收一个函数作为参数装饰器可以参数,这时候需要编写一个返回装饰器的高阶函数。高阶函数接收装饰器参数,并返回一个装饰器函数,装饰器函数再接收被装饰的函数,并返回一个新的函数对象。通过这种方式,我们可以传递不同的参数装饰器,实现不同的功能。 在使用装饰器时,为了保留原函数的元信息,如函数名、文档字符串等,可以使用`functools.wraps`修饰内部新函数,将新函数的属性设置为原始函数的属性,以便更好地还原被装饰函数的原始属性。 总结一下,Python装饰器是一种为函数或类添加额外功能的机制,它可以在不修改原函数源代码的情况下,通过闭包的方式实现功能的扩展。装饰器可以参数,并且可以用来装饰函数、方法或类。通过使用装饰器,我们可以更加灵活地扩展和改变函数的行为。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值