python装饰器的使用

python装饰器的使用

1、python装饰器的作用是什么?

它可以使我们的代码看起来更简洁,可以修改部分函数功能,让你的代码看起来很“高级”,当然,它也可能会造成代码的阅读性变差,所以在使用装饰器的时候,你需要做一个取舍。

2、当一个函数使用一个装饰器的时候发生了什么?

首先来看一段代码:

def param_func():
    return "hi, im a function"

def decoration(function):
    print("hi, im a decoration")
    print(function)

decoration(param_func)

相信大家一眼就能看明白,python中函数是可以作为另一个函数的参数的,实际上,这就已经创建了一个装饰器,简单修改一下上面的代码使其看起来更像装饰器:

def name():
    print("hi, im zhangSan")

def decoration(name):
    def set_sex_age():
        print("hi, im a boy")
        name()
        print("hi, im 16 years old")
    
    return set_sex_age

name = decoration(name)
name()

上面这段代码描述的就是函数装饰器所作的事情,它封装一个函数且修改其行为,现在,我们换成使用@符号来修改上面这段代码:

def decoration(name):
    def set_sex_age():
        print("hi, im a boy")
        name()
        print("hi, im 16 years old")

    return set_sex_age

@decoration
def name():
    print("hi, im zhangSan")

name()

这里存在了一个问题,如果你打印name.__name__,就会发现输出是set_sex_age,函数名字被重写了,因此可以使用下面的方式来解决:

from functools import wraps

def decoration(name):
    @wraps(name)
    def set_sex_age():
        print("hi, im a boy")
        name()
        print("hi, im 16 years old")

    return set_sex_age

@decoration
def name():
    print("hi, im zhangSan")

name()
print(name.__name__)

3、带参数的装饰器:

同样,使用装饰器也可以带参数,它的好处就不用说明了:

from functools import wraps

def people_decoration(age=16):
    def decoration(name):
        @wraps(name)
        def set_sex_age():
            print("hi, im a boy")
            name()
            print(f"hi, im {age} years old")
        return set_sex_age
    return decoration

@people_decoration(age=18)
def zhangSan():
    print("hi, im zhangSan")

@people_decoration()
def liSi():
    print("hi, im liSi")

zhangSan()
liSi()

4、装饰器类:

装饰器类的好处之一就是可以被继承:

from functools import wraps

class People_decoration(object):
    def __init__(self, sex='boy', age='16'):
        self.sex = sex
        self.age = age

    def __call__(self, name):
        @wraps(name)
        def decoration(*args, **kwargs):
            print(f"hi, im a {self.sex}")
            name()
            print(f"hi, im {self.age} years old")
        return decoration

@People_decoration()
def zhangSan():
    print("hi, im zhangSan")

@People_decoration(sex="girl", age="18")
def liSi():
    print("hi, im liSi")

zhangSan()
liSi()

其中用到了__call__,可以简单理解为__call__()重载了(),使得类的实例对象可以直接像调用普通函数那样直接调用:对象名()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值