博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python装饰器的个人小理解
阅读量:5021 次
发布时间:2019-06-12

本文共 2680 字,大约阅读时间需要 8 分钟。

个人对Python的装饰器小理解

标签: Python 装饰器 设计模式


刚刚开始学Python的时候看的廖雪峰先生的学习笔记,囫囵吞枣看了一遍就撸起袖子开干了,对Python很多特殊功能的理解其实并没有多深入。相信很多人也是一样,只是为了使用Python的某个库而入坑,而没有深入的学习Python这门语言。那么就让我们从装饰器开始,由浅入深吧。

什么是装饰器?

装饰器我将它理解为在不修改函数内部的前提下,对函数的一个“强化”。装饰器的使用其实一开始我还是挺懵逼的,后来慢慢开始理解到闭包、函数对象之后,对装饰器又有了新的理解,原来装饰器能做的事情还是很多的。那么我们就一步步的去理解到底什么是装饰器吧。

闭包的概念

大家都知道,在函数式编程中,函数内部就是一个作用域,更底层的讲,一个函数被调用时,它的内存空间其实只在进程内存空间的一个栈中。当函数调用完成返回时,操作系统就会回收这个栈,所以函数内部的所有变量的生存期只存在于这个函数被调用的时候。

在Python中,函数是可以嵌套定义的,比如说:

def outer(value):    def inner():        value = 10        print value    inner()    return valueans = outer(20)print ans

运行得到的结果:

1020

而在Python中,一切皆为对象,因此函数也能够作为对象被返回,进而被调用。举个栗子:

def outer():    def inner():        print "I'm inner!!!"    return inner    obj = outer()obj()

运行得到的结果:

I'm inner!!!

那么如果这个返回的函数内部使用了作用域仅在outer()函数中的变量,按理说这样调用inner()是会出错的。但是在Python中的闭包特性,令这一“违反常理”的操作可执行:

def outer(value):    def inner():        print "value is "%value    return inner    obj_fun = outer(0) #照理说value在这次函数调用后就应该被释放了obj_fun()

运行得到的结果:

outer_value is 0

在这里,函数inner()就是一个闭包,这个“包”里不仅仅装了函数的逻辑,也装了函数运行所需要的数据(或者说对象)。到目前来看,闭包好像还是没什么卵用,但是你想想,如果我们的参数不是一个“value”,而是一个“function”,那会怎么样?比如说:

def outer(func, value):    def inner():        print "run parameter of function before."        func(value)        print "run parameter of function after."    return innerdef speak(value):    print "+%ds "%(value)new_speak = outer(speak, 1)new_speak()

运行结果为:

run parameter of function before.+1srun parameter of function after.

装饰器

可能有的同学到现在还不理解到底闭包能干什么,那好我们现在设想一个情景:

之前在我们的网站中,某一个URI对于所有外来的的get请求都可以返回一句“苟利国家生死以”,但是现在觉得有些人不是同道中人,需要对这些请求加一些验证,只有请求头中包含Agent : real fans字段的用户才能收到这句话。

如果要在处理请求的函数里直接修改,那函数显然会越来越臃肿,让之后的人看着蛋疼,这时候装饰器就大派用场了:

from server import handler  #handler is a functionfrom Request import get_requestfrom log import log_inputnew_request = get_request()def wrapper(func, request):    def checker():        if not request.header.CheckHeader({"Agent":"real fans"}):            log_input("this guy is not hasi")            return None        else:            log_input("real fans!")            return func(request)    return checker        new_handler = wrapper(handler, new_request)new_handler()

这样,在完全不修改函数handler()的前提下,解决了这个问题。如果之后要扩大福利,不需要验证,那样也不需要对代码进行多少修改就能达到效果。什么?你还觉得太麻烦?!幸好程序员的懒惰就是业界进步的阶梯,Python为了让大家能更早的收工,增加了一个对装饰器的语法糖:

def outer(func):    def inner(value):        print "run parameter of function before."        func(value)        print "run parameter of function after."    return inner@outerdef speak(value):    print "+%ds "%(value)speak(1)

运行结果为:

run parameter of function before.+1srun parameter of function after.

是不是更简单了呢。

以上是个人粗浅的一点认识,之后有更深入了解会及时回来更新的

2017.7.3

转载于:https://www.cnblogs.com/nicholas-920610/p/7108698.html

你可能感兴趣的文章
dapper使用时性能优化
查看>>
POJ 2001 Shortest Prefixes(字典树)
查看>>
【Silverlight】汉诺塔游戏,带AI
查看>>
BigDecimal的引入和概述
查看>>
Oracle database server architecture
查看>>
StrictMode 详解
查看>>
LeetCode--Remove Duplicates from Sorted List
查看>>
(15)JavaScrip 的一些简单笔记
查看>>
右左法则解决复杂声明
查看>>
Jenkins的新建job和配置job
查看>>
三大类加载器 经典例子
查看>>
nohub命令
查看>>
光照问题之常见算法比较(附Python代码)
查看>>
【转】android颜色对应的xml配置值
查看>>
Java加密解密相关
查看>>
LeetCode & Q88-Merge Sorted Array-Easy
查看>>
这个2012不寻常
查看>>
web基础1
查看>>
接口测试框架1
查看>>
primefaces p:tableData 显示 List<List>
查看>>