Python两种装饰器的写法

python中有装饰器一说, 普遍的装饰器是修饰函数的, 长这样:

def fn(f):
    def func():
        print('pre do any')
        f()
        print('after do any')
    return func

@fn
def doAny():
    print('do any')

# doAny = fn(doAny)    上面的@fn为装饰器的常用形式, 此处为装饰器的实际运行过程

doAny()

通过这样, 我们就可以实现一个普通的函数装饰器, 利用装饰器我们可以很方便的为函数扩展功能, 例如实现拦截功能,或者针对别人写的函数做一些扩展都是可以的。

而我们常见的其实还有一类装饰器, 那就是用于类的装饰器, 虽然形式大同小异, 但是还是有点点不同的

def decorator(n):
    def func(fn):
        print('pre do any')
        fn.age = n
        print('end do any')

        # 可以看到类装饰器多了这么一句,实际上传入的fn为一个类, 所以需要确保你写的装饰器调用之后,仍然能返回一个类, 所以在这里要返回fn
        return fn        
    return func

@decorator(25)      # 这是类装饰器的常用形式, 例如@admin.register(Group),是不是很常见?
class Person:
    def __init__(self, name):
        self.name = name

# Person = decorator(3)(Person)     # 这是类装饰器实际的调用过程, 很丑...

print(type(Person))

p = Person('will')
print(p.name, p.age)

通过上述代码, 我们可以看到修饰类的装饰器,在内部的函数中返回了fn, 这是因为修饰后的类必须保证依然是原类, 通过类装饰器我们可以在类上面挂载很多东西, 比如类方法, 类属性等等...通过上面的例子, 就给Person类挂载了age类属性。

需要注意的是, 因为在调用过程中传递的都是类, 所以扩展的属性都是类属性, 所以如果需要为类添加属性的时候才使用这种模式,为什么强调这点呢, 因为类属性是所有实例共有的...

上面只是个简单的例子, 实际上,你在真实的代码的时候是可以利用关键字传参的,之后再在内部函数中调用setattr轻松为类进行扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值