初学Python——装饰器
一、什么是装饰器
当我们做好一个产品之后,需要对它进行不断地维护,对某些函数增加一些功能。这个时候如果去修改源代码将是非常不合适的。(原因:1.原则上已经写好的函数尽量不去修改它,因为一旦修改可能会导致不可预知的错误发生或者降低稳定性。2.函数可能被调用很多很多次,如果修改函数有可能会导致调用方式发生改变,会有大量的修改工作。)所以,装饰器就出现了。它可以做到为函数增添新功能的同时而不修改函数本身的源代码。
二、装饰器的原则
1.不能修改被修饰函数的源代码
2.不能修改被修饰函数的调用方式
三、实现装饰器的知识储备
1.函数即“变量”:定义一个函数,相当于将函数体赋值给函数名这个变量。
2.高阶函数:满足以下两个条件之一的函数即为高阶函数:①把函数名当做实参传给另一个函数②返回值中包含函数名
3.嵌套函数:函数是可以嵌套的
四、使用装饰器
高阶函数+嵌套函数=装饰器
装饰器的本质是函数,功能是为其它函数添加附加功能
#现在有两个函数,分别有各自的功能,需求是计算每个函数运行的时间 def text1(): time.sleep(2) print("this is text1") def text2(*args,**kwargs): time.sleep(2) print("this is text2",args[0],args[1])
可以写装饰器:
def timer(func): def deco(*args,**kwargs): start_time=time.time() func(*args,**kwargs) end_time=time.time() print("the function tun time is {0}".format(end_time-start_time)) return deco
其中func()函数是原函数真正的执行过程,deco函数内其他的语句都是新添加功能的语句
装饰器名叫timer
写好装饰器就行了吗?不是,还差一个步骤,在原函数上方增加一条语句,整合到一起:
def timer(func): def deco(*args,**kwargs): start_time=time.time() func(*args,**kwargs) end_time=time.time() print("the function tun time is {0}".format(end_time-start_time)) return deco @timer #此操作的作用是将装饰器的功能加到原函数上 相当于text1=timer(text1) def text1(): time.sleep(2) print("this is text1") @timer #没有@timer语句则不会将装饰器功能加上 def text2(*args,**kwargs): #如果原函数有参数,需要在装饰器中deco上加参数 time.sleep(2) print("this is text2",args[0],args[1]) text1() #不改变调用方式,且增加了新功能 text2(29000,"hello")
装饰器解析:deco函数用来实现新增功能,timer函数和@timer语句用来使调用方式不发生改变
执行结果:
五、带参数的装饰器
这里说的不是原函数带参数,而是装饰器函数本身带参数
现在有需求,用装饰器实现登陆过程,并且有两种不同的登陆方式:使用本地数据登陆和使用云端数据登陆
#现在有三个网页,其中登陆home时用本地数据,登陆bbs时用云端数据 def index(): print("welcome to index page") def home(): print("welcome to home page") return "form home" def bbs(): print("welcome to bbs page")
需要装饰器:
name="alex" word="123" def auth(auth_type): def auth_out(func): def deco(*args,**kwargs): if auth_type=="local": #如果使用本地数据 uesrname=input("请输入用户名:").strip() password=input("请输入密码:").strip() if uesrname==name : # 如果用户存在 if password==word:#如果密码正确 print("使用本地数据") print("欢迎进入!") return func(*args,**kwargs) #进入home界面 else: print("密码错误") else: print("用户不存在") elif auth_type=="cloude": #如果使用云端数据 print("使用云端数据") print("欢迎") func() # 进入bbs界面 return deco return auth_out def index(): print("welcome to index page") @auth(auth_type="local") #登录home界面使用本地用户数据,在auth()内传参 def home(): print("welcome to home page") return "form home" @auth(auth_type="cloude") #登录bbs界面使用云端用户数据 def bbs(): print("welcome to bbs page") index() print(home()) bbs()
其实就是将原来的装饰器外层又嵌套了一层函数,用来传递参数。@语句也变成了@auth(auth_type=" ")
运行结果:
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Jenkins ant build.xml文件详解(学习笔记六)
ANT build.xml文件详解(一) Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道 make这个命令。当编译Linux内核及一些软件的源程序时,经常要用这个命令。Make命令其实就 是一个项目管理工具,而Ant所实现功能与此类似。像make,gnumake和nmake这些编译工具都有 一定的缺陷,但是Ant却克服了这些工具的缺陷。最初Ant开发者在开发跨平台的应用时,用样也 是基于这些缺陷对Ant做了更好的设计。 Ant 与 makefile Makefile有一些不足之处,比如很多人都会碰到的烦人的Tab问题。最初的Ant开发者多次强调” 只是我在Tab前面加了一个空格,所以我的命令就不能执行”。有一些工具在一定程度上解决了 这个问题,但还是有很多其他的问题。Ant则与一般基于命令的工具有所不同,它是Java类的扩 展。Ant运行需要的XML格式的文件不是Shell命令文件。它是由一个Project组成的,而一个 Project又可分成可多target,target再细分又分成很多task,每一个task都是通过一个实...
- 下一篇
【python进阶】Garbage collection垃圾回收1
前言 GC垃圾回收在python中是很重要的一部分,同样我将分两次去讲解Garbage collection垃圾回收,此篇为Garbage collection垃圾回收第一篇,下面开始今天的说明~~~ 1.Garbage collection(GC垃圾回收) 现在的⾼级语⾔如java,c#等,都采⽤了垃圾收集机制,⽽不再是c,c++⾥ ⽤户⾃⼰管理维护内存的⽅式。⾃⼰管理内存极其⾃由,可以任意申请内存,但如同⼀把双刃剑,为⼤量内存泄露,悬空指针等bug埋下隐患。 对于⼀个字符串、列表、类甚⾄数值都是对象,且定位简单易⽤的语⾔,⾃然不会让⽤户去处理如何分配回收内存的问题。 python⾥也同java⼀样采⽤了垃圾收集机制,不过不⼀样的是: python采⽤的是引⽤计数机制为主,标记-清除和分代收集两种机制为辅的策略。引⽤计数机制:python⾥每⼀个东⻄都是对象,它们的核⼼就是⼀个结构体: PyObject typedef struct_object{ int ob_refcnt; struct_typeobject *ob_type; }PyObject; PyObject是每个对象必...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- 设置Eclipse缩进为4个空格,增强代码规范
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能