Python中装饰器浅析

最近在看廖雪峰的Python教程,看到装饰器部分,比较难懂,折腾了两天总算有点心得,跟大家分享一下。

以下代码的开发环境为Python 3.4.3。

装饰器对应的是设计模式中的装饰模式(Decorator Pattern),根据百度百科的解释,是指在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,通过创建一个包装对象,包裹真正的对象。装饰模式遵循了面向对象开放中的开放封闭原则即封闭:以实现的功能代码块;开放:对扩展开放。

下面是一个简单的示例:

def log(func):
    print("*"*10,"Something unexpected happened","*"*10)
    def wrapper(*args,**kwargs):
        print("即将开始运行")
        result = func()
        print("运行已经结束")
        return result
    return wrapper

@log
def test():
    print("This is just a test.")

#test()
print(test.__name__)

运行示例程序,可以看出在示例程序中并未执行test()(被注释),但实际有输出:
********** Something unexpected happened **********
wrapper

再进一步分析装饰过程,发现原来装饰过程在函数test定义的时候就已经执行了。Python代码按照自上向下的顺序执行:

1.遇到log函数的定义,由于未进行调用,会将log的函数体加载进内存,并不会执行,之后继续。

2.遇到@log这个语法糖时,程序认出这是装饰器,按照装饰器的规则进行执行,被装饰的函数名func会被传递给装饰函数,此时装饰函数会进行执行,因此会有上述打印。

另外通过打印出的函数名可以看出,test函数此时已经被包装成了wrapper函数,即之后执行test()时,实际是在执行被装饰的wrapper函数

对于装饰函数的最里层函数,最好再加上“@functools.wraps(func)”的修饰,这样就能保留原函数的特殊属性。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值