python 3.x 的装饰器笔记
今天学到了python的装饰器,感觉这个东西还是稍微有些复杂,所以记录下来,方便以后的查找。虽然标题是python 3.x的装饰器,但是我也没有怎么用过python 2.x,感觉上应该是和python 2.7在用法上差不多。
现在某个视频公司有一段代码,,代码的主要功能就是看电影。
def watchfilm():
print('You are watching film now....') watchfil()
运行之后输出:
You are watching film now....
现在要求来了,老板提出看电影之前必须要进行登录。
此时小A想到开放封闭原则,原有的代码不能更改,但是需要进行扩展。于是小A有了以下想法:
1.可以定义一个登录函数,将看电影函数的内存地址作为参数传入
2.运行登录函数,将原先看电影函数的内存地址返回
3.使用新的变量存储原先看电影函数的内存地址,将新变量和原先看电影函数的函数名定义为相同的名字
4.运行新变量的时候就就会找到内存地址,运行原先看电影函数的代码
基于以上想法,小A写出了如下代码:
def login(func):
print('username&password verification....')
return func def watchfilm():
print('You are watching film now....') watchfilm=login(watchfilm)
watchfilm()
运行之后输出:
username&password verification....
You are watching film now....
老板看后很满意,然后说:不行!
因为看电影函数是基础平台,而调用是业务部门再进行调用,如果这样修改,就需要业务部门修改大量的代码。
方案被老板否定了,但是活还得接着干啊。小A一筹莫展。
某一天,小A遇见了小B,向小B倾诉了自己的苦恼,小B说道:“使用python的装饰器啊。”
小B解释到,装饰器实现的东西和你做的东西是一样的,不过装饰器使用语法糖@来装饰函数。装饰器执行时,把被装饰函数的内存作为参数传给装饰器,同时执行装饰器函数,最后返回新定义的函数名,和被装饰的函数名相同,只不过内存地址可不一定就是被装饰的函数的内存地址了。再执行被装饰函数时,其实执行的是新的函数。
小A一听,有门,来了精神。经过了一段时间的研究,于是有了一下代码:
def login(func):
print('username&password verification....')
return func @login
def watchfilm():
print('You are watching film now....') watchfilm()
运行之后输出:
username&password verification....
You are watching film now....
能够满足要求,小A顿时兴奋起来。小A马上又测试了几次,没有问题。就在小A想着可以交差的时候,他发现了一个问题。
def login(func):
print('username&password verification....')
return func @login
def watchfilm():
print('You are watching film now....') print('other operation.....')
watchfilm()
运行之后输出:
username&password verification....
other operation.....
You are watching film now...
明明没有调用函数,为什么会有输出呢?登录程序应该是在其它操作之后,看电影之前才对啊?小A看了看程序,马上明白了问题所在,因为程序只要启动,就会执行装饰器函数,执行装饰器函数就会执行登录程序,导致了现在这种情况。
这样不行啊,怎么才能解决呢?
忽然小A灵机一动,想到了一个办法,于是有了代码2.0
def login(func):
def inner():
print('username&password verification....')
func()
return inner @login
def watchfilm():
print('You are watching film now....') print('other operation.....')
watchfilm()
运行之后输出:
other operation.....
username&password verification....
You are watching film now....
完美解决了问题,小A长出了一口气。
第二天,小A赶紧找到老板,说出了自己的想法。
老板满意的点点头,对小A说道:你做的很好,但是现在咱们需求变了,目前还想在看电影之前放一段广告而且看完电影之后推荐几部电视节目,你看咱们能不能实现一下。
小A虎躯一震,擦了擦头上的汗,点头应承了下来。但是小A此时也犯了难,如何使用装饰器进行实现呢?小A想到了小B,于是赶紧去请教小B,一顿酒肉计下来,小B跟小A说,你想想装饰器的原理,如果我在有一层def呢?小A一拍大腿,对啊,我怎么没有想到。
小A赶紧进行设计,于是有了代码3.0
def advert():
print('advertisement time...') def recommend():
print('recommend TV show...') def login(adv,rec):
def inner(func):
def inner2():
print('username&password verification....')
adv()
func()
rec()
return inner2
return inner @login(advert,recommend)
def watchfilm():
print('You are watching film now....') print('other operation.....')
watchfilm()
运行之后输出:
other operation.....
username&password verification....
advertisement time...
You are watching film now....
recommend TV show...
装饰器带参数之后会首先运行带参数的函数,本例中是login(advert,recommend),函数返回inner函数的内存地址,之后装饰器开始执行,就会变成执行@inner装饰器,之后因为之前两个函数已经传入过,所以再调用函数的时候就能显示输出了。
小A很高兴,这次真是又快又好的完成了任务,于是他唯恐事件有变,赶在老板下班之前向老板进行了汇报。
老板听了小A的汇报相当满意,高声称赞小A,忽然话锋一转,说道:但是小A啊,咱们的需求现在。。。。。。。
(未完待续)
python 3.x 的装饰器笔记的更多相关文章
- python函数与方法装饰器
之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...
- Python中利用函数装饰器实现备忘功能
Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下 " ...
- python设计模式之内置装饰器使用(四)
前言 python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python设计模式之装饰 ...
- python 中多个装饰器的执行顺序
python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inn ...
- Python函数编程——闭包和装饰器
Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...
- python基础-内置装饰器classmethod和staticmethod
面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...
- Python 入门之 Python三大器 之 装饰器
Python 入门之 Python三大器 之 装饰器 1.开放封闭原则: (1)代码扩展进行开放 任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代 ...
- python中面向对象之装饰器
python面向对象内置装饰器property,staticmethod,classmethod的使用 @property 装饰器作用及使用 作用:面向对象中的方法伪装成属性 使用如下: class ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
随机推荐
- CSS元素隐藏的11种方法
{ display: none; /* 不占据空间,无法点击 */ } { visibility: hidden; /* 占据空间,无法点击 */ } { position: absolute; cl ...
- 【nginx】一台nginx服务器多域名配置
Nginx 多域名配置 nginx绑定多个域名可又把多个域名规则写一个配置文件里,也可又分别建立多个域名配置文件,我一般为了管理方便,每个域名建一个文件,有些同类域名也可又写在一个总的配置文件里.一. ...
- Java 完美判断字符串中中文字符【中文符号】
package com.cmc.util; import java.util.regex.Pattern; public class CharUtil { public static void mai ...
- 玲珑oj 1028 贪心
http://www.ifrog.cc/acm/problem/1028 很有趣的一道题,求从n个数里挑出不同的两个,使得他俩'|','&','^'后的值尽量大,求这个最大的结果. 求最大的异 ...
- uva 12086 线段树or树状数组练习
题目链接 https://vjudge.net/problem/34215/origin 这个题就是线段树裸题,有两种操作,实现单点更新和区间和的查找即可,这里第一次学习使用树状数组完成. 二者相 ...
- NetHogs 实时检测网络流量 转
有很多适用于Linux系统的开源网络监视工具.比如说,你可以用命令iftop来检查带宽使用情况. netstat用来查看接口统计报告,还有top监控系统当前运行进程.但是如果你想要找一个能够按进程实时 ...
- zen cart 空白页面的解决方案
在安装zen cart 这套CMS时, 有时候会由于修改了某些页面或者是由于环境的某些组件的版本问题导致前台页面出现空白页, 由于在空白页面处没有任何提示, 并且在日志中也没有这样的出错提示, 导致在 ...
- debug调试日志和数据查询
手动删除es文件并释放磁盘空间 1.停掉服务 systemctl stop xsdaemon.service 2.删掉索引 rm -rf /home/storager/c3dceb5e-bacc-4a ...
- 四、dbms_alert(用于生成并传递数据库预警信息)
1.概述 作用:用于生成并传递数据库预警信息.使用包DBMS_ALERT,则必须以SYS登陆,为该用户授予执行权限.sql>conn sys/oracle as sysdbasql>gra ...
- HDU 4704 Sum (隔板原理 + 费马小定理)
Sum Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/131072K (Java/Other) Total Submiss ...