python成长日迹--装饰器

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

首先我们看一个简单的例子:

def info():
    print('hello')

我们实现了一个简单的函数:

  • 若此时,我们有了一个新的需求:打印hello并且打印日志
  • 那么可能大家都会想到,我添加一行打印日志的代码不就行了吗?
def info():
    print('hello')
    print('*******log1*******')

问题:

  • 假如你就几十个函数都需要添加日志,那么你就必须把每个日志都找到,然后一行一行地添加代码
  • 这样就会造成大量的重复代码,我们会不会在不动原函数的前提下实现我们的功能?

开放封闭原则:

  • 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

  • 对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。


# 这时可能有人想到了,我再创建个函数然后调用这个函数就可以实现,而且减少了代码重复

def info():
    print('hello')

def logger(func):
    func()
    print('******logger******')
info=logger(info)

相当于我们之前是使用info()函数实现打印,现在又要使用logger()函数实现,若是别人不知道logger这个函数,只知道有info这个函数,他只想调用info这个函数

装饰器就要登场了

def info():
    print('hello')


def logger(func):

    def inner():        #装饰后的代码(闭包)
        func()
        print('******logger******')
    return inner
'''    
不难理解,inner这个函数就是装饰器函数,也是一个闭包,此时我们调用logger这个函数,返回了inner
我们再用info=logger(info)=inner,然后再使用info()就实现了扩展
'''
info=logger(info)
info()

# 还有一个问题,就是需要打印日志的函数很多,我们每次都要写

func=logger(func)
func()

这样也会很麻烦,还有没有更简便的方式,其实,python为我们提供了一个更简单的方式,使用(@装饰器函数)即可

  • 但是装饰器函数必须写在你要使用的函数之前,否则就找不到你的装饰器函数
def logger(func):

    def inner():
        print('******logger******')
        func()

    return inner


@logger         #这里的@logger就相当于info=logger(info)
def info():
    print('hello')

info()
@logger
def bar():
    print('GoodMorning!')

** 扩展:若我们的函数是个带参函数且有返回值,那么我们装饰器部分的形参可以使用*args和**kwargs

def result(func):

    def inner(*args,**kwargs):
        print('******logger*******')

        return func(*args)      
        #我们的函数存在返回值,若想的到返回值,就必须将该函数返回至上一层,一层一层传递,就可以最终得到原函数的返回值

    return inner

@result
def add(*args):     #一个加法运算的函数
    num=0
    for i in args:
        num+=i
    print(num)
    return num
print(add(1,2,3))     #最终得到原函数的返回值6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值