博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python的高级特性7:闭包和装饰器
阅读量:5807 次
发布时间:2019-06-18

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

本节跟第三节关系密切,最好放在一起来看:

一.闭包:闭包不好解释,只能先看下面这个例子:

In [23]: def outer(part1):   ....:        def inner(part2):   ....:                return part2*part1   ....:        return inner   ....: In [24]: f = outer(33)In [25]: f(100)Out[25]: 3300In [26]: f(11)Out[26]: 363

在这个例子中实现了一个功能: f (x) =33*x ,其中f(x)代表了内层函数的功能体,x代表内层函数的参数,也就是说outer函数返回了一个函数,而这个函数的参数(33)来自外层函数,我们可以把外层函数的参数理解成配置,于是通过配置的不同,我们便得到了不同的运算结果,这就叫闭包。

ps:闭包的实现得益于__call__方法,而装饰器就是闭包,也就是说如果要理解装饰器,一定要重视__call__这个内建方法。

 

二.装饰器

装饰器是面向切面编程的基础,Java的AOP相当成熟,它可以很方便的把日志,事务处理等功能给分离出去,而开发者只要专注于业务的开发即可。Python的AOP编程没有什么认可度很高的轮子,但自己写起来也并不麻烦,下面举一个例子。

假设需要提供一个功能给别人,当别人输入了文件路径,我们这个功能就能把这个文件给读取出来,并给出它的运行时间。

想象一下人格分裂的场景,现在我们需要两个不同的人:装饰器函数和"配置函数".

装饰器函数:我需要你提供一个文件路径,只要你在函数上加上语法糖,就能知道这个文件的内容和读取时间啦!

配置函数:我返回一个路径就能读取文件了?我书读得少,你可不要骗我。

import time #装饰器函数def readFile(func):    def _deco(path):        start_time = time.time()        f = open(func(path),'r')        end_time = time.time()        print("readFile costs %ss." % (end_time - start_time))        return f.read()    return _deco#配置函数@readFiledef location(path):    return pathprint(location('/tmp/tt.txt'))

运行结果是:

sh-3.2# python readFile.py readFile costs 5.412101745605469e-05s.装饰器测试

这是一种比较简单的装饰器,其实调用是@readFile = readFile(location).

下面再看装饰器带参数的例子,这也是flask里用得最多的。

class locker:    def __init__(self):        print("locker.__init__() should be not called.")    @staticmethod    def acquire():        print("locker.acquire() called.(这是静态方法)")def deco(cls):    def _deco(func):        def __deco():            print("before %s called [%s]." % (func.__name__, cls))            cls.acquire()            return func()        return __deco    return _deco@deco(locker)def myfunc():    print(" myfunc() called.")myfunc()

这段代码参考了:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html的第7步.

装饰器写起来比理解起来容易。只有自己着手去写,才能真正理解装饰器。

这里有一篇关于装饰器讲解质量相当高的博文:http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

 

你可能感兴趣的文章
python matplotlib 中文显示参数设置
查看>>
数据库事务隔离级别
查看>>
os模块大全详情
查看>>
【ros】Create a ROS package:package dependencies报错
查看>>
从内积的观点来看线性方程组
查看>>
kali linux 更新问题
查看>>
HDU1576 A/B【扩展欧几里得算法】
查看>>
廖雪峰javascript教程学习记录
查看>>
WebApi系列~目录
查看>>
限制CheckBoxList控件只能单选
查看>>
Java访问文件夹中文件的递归遍历代码Demo
查看>>
项目笔记:测试类的编写
查看>>
如何迅速分析出系统CPU的瓶颈在哪里?
查看>>
通过容器编排和服务网格来改进Java微服务的可测性
查看>>
re:Invent解读:没想到你是这样的AWS
查看>>
PyTips 0x02 - Python 中的函数式编程
查看>>
阿里云安全肖力:安全基础建设是企业数字化转型的基石 ...
查看>>
使用《Deep Image Prior》来做图像复原
查看>>
如何用纯 CSS 为母亲节创作一颗像素画风格的爱心
查看>>
Linux基础命令---rmdir
查看>>