python的装饰器学习和使用

为何需要装饰器

假设你写了一个购物程序,里面有三个函数分别是加入购物车/付款/确认收货,而这三个函数可能都需要
验证用户登陆操作,一种方法是写一个函数然后分别在之前函数块中引用这个验证登陆的函数,另一种就是装饰器:

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。

初级装饰器

下面是之前的装饰器实现,以函数为参数传入,然后实现功能:

# 这个是装饰器,实现功能是登陆验证
def wrapper(func):
    def inner():
        print('登录验证')
        func()
    return inner


@wrapper
def cost():
    print('付款')


@wrapper
def join_car():
    print('加入购物车')


@wrapper
def confirm():
    print('确认收货')


if __name__ == '__main__':
    cost()

带参数的装饰器

当你需要传入参数的时候,Python提供了可变参数*args和关键字参数**kwargs,有了这两个参数,装饰器就可以用于任意目标函数了。

def wrapper(func):
    def inner(*args, **kwargs):
        print('登录验证')
        func(*args, **kwargs)
    return inner


@wrapper
def confirm(num, price):
    print('确认收货%d个%d块钱'%(num, price))

if __name__ == '__main__':
    confirm(1, 20)

输出结果:

登录验证
确认收货1个20块钱

高级一点的装饰器

装饰器工厂

其实装饰器工厂就是根据参数返回一个装饰器,本质上也只是函数嵌套

def get_celebrator(char):
    def print_style(func):
        def inner():
            print(char*15)
            func()
        return inner
    return print_style


@get_celebrator('=')
@get_celebrator('*')
def my_print():
    print("小白联盟")
  
my_print()   

多层装饰

上面一层代码已经用到多层装饰,打印结果为:

===============
***************
小白联盟

加载顺序是从下往上加载,先返回一个被装饰器装饰过的函数,再继续装饰(‘=’)所以先打印======

类装饰器

简单用__call__实现即可:

class Logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print('logging')
        return self.func(*args, **kwargs)


@Logging
def say(something):
    print (something)

say('hello python')

类给类的装饰器

给已经写好的类加功能,因为.方法调用类属性或者类方法时会通过__getattr__,所以类装饰器可以这么写,在装饰器类里的__getattr__添加功能即可

class Mydatabase:
    abc = 1
    def delete(self):
        print('delete')

    def create(self):
        print('create')

class DecotatorDB:
    def __init__(self,db):
        self.db =db

    def __getattr__(self, item):
    	# 这里添加功能
        return getattr(self.db,item)

# 这是个前面的类加功能
d = DecotatorDB(db=Mydatabase())
d.create()
d.delete()
print(d.abc)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值