作为许多语言都存在的高级语法之一,装饰器是你必须掌握的知识点。
装饰器(Decorator):从字面上理解,就是装饰对象的器件。可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将
装饰器名,放在被装饰对象上面。decdeffunc():pass在进行装饰器的介绍之前,我们必须先明确几个概念和原则:
首先,Python程序是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行的,只有等到该函数被调用时,才会执行其内部的代码块。关于这一点,其实我们在前面的章节已经介绍过了。
deffoo():print("foo函数被运行了!")#如果就这么样,foo里的语句是不会被执行的。#程序只是简单的将定义代码块读入内存中。#foo()只有调用了,才会执行
其次,由于顺序执行的原因,如果你真的对同一个函数定义了两次,那么,后面的定义会覆盖前面的定义。因此,在Python中代码的放置位置是有区别的,不能随意摆放,通常函数体要放在调用的语句之前。
deffoo():print("我是上面的函数定义!")foo()deffoo():print("我是下面的函数定义!")foo()#----------------执行结果:我是上面的函数定义!我是下面的函数定义!
然后,我们还要先搞清楚几样东西:函数名、函数体、返回值,函数的内存地址、函数名加括号、函数名被当作参数、函数名加括号被当作参数、返回函数名、返回函数名加括号。
defouter(func):definner():print("我是内层函数!")returninnerdeffoo():print("我是原始函数!")outer(foo)outer(foo())
函数名:foo、outer、inner
函数体:函数的整个代码结构
返回值:return后面的表达式
函数的内存
deff1():#加入认证程序代码print("业务部门1数据接口......")deff2():#加入认证程序代码print("业务部门2数据接口......")deff3():#加入认证程序代码print("业务部门3数据接口......")deff():#加入认证程序代码print("业务部门数据接口......")#各部门分别调用f1()f2()f3()f()
第四天:主管又换了个开发工程师。他是这么干的:定义个认证函数,在原来其他的函数中调用它,代码如下。
deflogin():print("认证成功!")deff1():login()print("业务部门1数据接口......")deff2():login()print("业务部门2数据接口......")deff3():login()print("业务部门3数据接口......")deff():login()print("业务部门数据接口......")#各部门分别调用f1()f2()f3()f()
但是主管依然不满意,不过这一次他解释了为什么。主管说:写代码要遵循开放封闭原则,简单来说,已经实现的功能代码内部不允许被修改,但外部可以被扩展。如果将开放封闭原则应用在上面的需求中,那么就是不允许在函数f1、f2、f3......f的内部进行代码修改,但是可以在外部对它们进行扩展。
第五天:已经没有时间让主管找别人来干这活了,他决定亲自上阵,使用装饰器完成这一任务,并且打算在函数执行后再增加个日志功能。主管的代码如下:
defouter(func):definner():print("认证成功!")result=func()print("日志添加成功")returnresultreturninner
outerdeff1():print("业务部门1数据接口......")outerdeff2():print("业务部门2数据接口......")outerdeff3():print("业务部门3数据接口......")outerdeff():print("业务部门数据接口......")#各部门分别调用f1()f2()f3()f()使用装饰器
outer,也是仅需对基础平台的代码进行拓展,就可以实现在其他部门调用函数API之前都进行认证操作,在操作结束后保存日志,并且其他业务部门无需对他们自己的代码做任何修改,调用方式也不用变。以上就是Python装饰器的详解,私信回复,免费领取Python编程全套学习资料,包含全套视频教程、项目源码、学习路i线图等,赶快私信吧!