在实际中,我们可能需要在不改变函数源代码和调用方式的情况下,为函数添加一些新的附加功能,能够实现这种功能的函数我们将其称之为装饰器。装饰器本质上其实还是是一个函数,用来装饰其它函数,为函数添加一些附加功能。下面我将具体讲解一下如何实现装饰器。

具体剖析上面的叙述,我们可以分析出装饰器应该具有的性质:

 1.不能修改被装饰的函数的源代码(在不修改被装饰函数的源代码的情况下,为其添加功能)

   2.函数的调用方式不能被修改(函数的调用方式不用被修改)

以上两个性质实则对应着函数里面的三个知识点:函数即‘变量’、高阶函数、函数嵌套。可以说 高阶函数+函数嵌套 = >装饰器

函数即变量

  我们知道变量有内存回收机制,函数和变量一样也有同样的性质,函数在内存中的存储方式就可以看做是一段存储在内存中的代码,和变量没有任何区别。
 def foo():
print('you are the best girl!\n')
print(foo)
  如上面这段代码,执行print的时候,会同变量一样,返回一个函数存储在内存的首地址;当为foo加上括号才表示执行该函数。
高阶函数 满足下列两个条件之一就叫做高阶函数:把一个函数名当做实参传给另外一个函数(注意是函数名,如果函数名后面加了括号表示传递的是该函数的返回值,
不能算作高阶函数,后同);返回值中包含函数名
import time
def add():
print('a+b = 10')
time.sleep(2) def decorate(func):
start_time = time.time()
func()
stop_time = time.time()
print('the func run time is %s'%(stop_time - start_time)) decorate(add) #此方式可直接运行函数 #函数返回,可以直接返回函数的地址,变量接收到函数地址后,可以以该变量作为函数名调用函数
# def test2(func):
# func()
# print(func)
# return func
#
# add = test2(add)
# add() #add接收到函数首地址后,再加上小括号就可以直接运行该函数

函数嵌套

 嵌套函数(*注意函数嵌套与函数调用的区别)
def test3():
print('in the test3')
def next(): #相当于在test3函数里面定义了一个局部变量函数
print('int the next func')
next() test3()
装饰器
在理解了以上概念之后便可以直接上装饰器的源代码了
#装饰器功能,检验用户是否有资格登录使用该函数,并显示登录时间
import time
username,password = "putin","zy123456"
def loging(intype = 'local'):#这一层是接收在使用装饰器时,装饰器需要传入的参数
def out_warper(func): #这一层是传入函数名称
def warper(*args,**kwargs):
if intype == 'local': #使用本地用户登录
user = input("Username:").strip()
passwd = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1m User has passed\033[0m")
timeformat = '%y-%m-%d, %X' #显示登录的时间
timecuren = time.strftime(timeformat)
print("登录时间: %s" %timecuren)
res = func(*args,**kwargs) #可以返回函数的使用值
print('the end')
return res
else:
#\033[31;1m格式是设置字体颜色的
exit("\033[31;1m Ivalid input\033[0m")
elif intype == 'ldap':
print("目前暂不支持LDAP登录!")
return warper
return out_warper @loging() #相当于 home = loging(intype = 'local')
def home():
print("welecome to the home")
return("welecome come to home next time") @loging(intype = 'ldap') #相当于 home = loging(intype = 'ldap')
def bbs():
print("welecome to the bbs")
return("bbs come to next time") home()
bbs()
由于水平有限,以上讲述可能存在问题,希望多多更正
 
												

Python之函数装饰器的更多相关文章

  1. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  2. python基础-----函数/装饰器

    函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 函数的优点之一是,可以将代码块与主程 ...

  3. Decorator——Python初级函数装饰器

    最近想整一整数据分析,在看一本关于数据分析的书中提到了(1)if __name__ == '__main__' (2)列表解析式 (3)装饰器. 先简单描述一下前两点,再详细解说Python初级的函数 ...

  4. python 复习函数 装饰器

    # 函数 —— 2天 # 函数的定义和调用 # def 函数名(形参): #函数体 #return 返回值 #调用 函数名(实参) # 站在形参的角度上 : 位置参数,*args,默认参数(陷阱),* ...

  5. day11 python之函数装饰器

    一,什么是装饰器? 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事 ...

  6. python 匿名函数&装饰器

    匿名函数 关键字lambda表示匿名函数,冒号前面的x表示函数参数匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果. >>> list(map(l ...

  7. python闭包函数&装饰器

    一.函数引用 函数可以被引用 函数可以被赋值给一个变量 def hogwarts(): print("hogwarts") # hogwarts() # 函数调用 print(ho ...

  8. python 之 函数 装饰器

    5.8 装饰器 1 开放封闭原则 软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的 也就是说我们必须找到一种解决方案: 能够在不修改一个功能源代码以及调用方式的前提 ...

  9. Python中函数装饰器及练习

    )])   ,,],)

随机推荐

  1. [转]优化IIS7.5支持10万个同时请求的配置方法

    通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请求数限制,TCPIP连接数等方面,从而使WEB服务器的性能得以提升,保证WEB访问的访问流畅 通过对IIS7的配置进行优化,调整IIS7应 ...

  2. mongo 聚合函数

    一: 聚合 常见的聚合操作跟sql server一样,有:count,distinct,group,mapReduce. <1> count count是最简单,最容易,也是最常用的聚合工 ...

  3. Zabbix监控mysql主从状态并实现报警

    一.环境需求 主机A: zabbix-server 主机B: zabbix-agent/mysql从 二.主机B操作 1.添加监控脚本 vim /data/zabbix/mysql_slave_che ...

  4. 来自Google资深工程师的API设计最佳实践

    来自Google资深工程师Joshua Bloch的分享:API设计最佳实践 为什么API设计如此重要?API是一个公司最重要的资产. 为什么API的设计对程序员如此重要? API一旦发布,出于兼容性 ...

  5. 关于notify() 和notifyAll() 一个需要注意的地方

    notify() 和 notifyAll()都是唤醒其他正在等待同一个对象锁的线程. 下面是我遇到的一个问题,记下来,免得忘了. 直接上代码,有错误的代码: 代码描述:有一个Caculate类,类中又 ...

  6. 【转】九步学习python装饰器

    本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白 ...

  7. 20、Springboot 与数据访问(JDBC/自动配置)

    简介: 对于数据访问层,无论是SQL还是NOSQL,Spring Boot默认采用整合 Spring Data的方式进行统一处理,添加大量自动配置,屏蔽了很多设置.引入 各种xxxTemplate,x ...

  8. 【转】java.lang.ClassNotFoundException: org.springframework.context.event.GenericApplicationListener

    http://www.cnblogs.com/softidea/p/6064091.html Caused by: java.lang.NoClassDefFoundError: org/spring ...

  9. springboot多数据源的配置与使用

    转自:https://www.jianshu.com/p/34730e595a8c 之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Sp ...

  10. VS调试_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));崩溃原因及解决方法

    今天下午对面的老大调试遇到这个问题,大家一起讨论好久才解决这个问题 crt源代码都是可以看到的,为了了解清楚原因,十分有必要查看源码,源码一般在你的VS安装路径下VC\crt\src下. 点击重试,定 ...