Python的高级特性7:闭包和装饰器
本节跟第三节关系密切,最好放在一起来看:python的高级特性3:神奇的__call__与返回函数
一.闭包:闭包不好解释,只能先看下面这个例子:
In [23]: def outer(part1):
....: def inner(part2):
....: return part2*part1
....: return inner
....: In [24]: f = outer(33) In [25]: f(100)
Out[25]: 3300 In [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 #配置函数
@readFile
def location(path):
return path print(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的高级特性7:闭包和装饰器的更多相关文章
- 13、python中的函数(闭包与装饰器)
一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...
- python 生成器,迭代器,闭包,装饰器
1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...
- Python虚拟机函数机制之闭包和装饰器(七)
函数中局部变量的访问 在完成了对函数参数的剖析后,我们再来看看,在Python中,函数的局部变量时如何实现的.前面提到过,函数参数也是一种局部变量.所以,其实局部变量的实现机制与函数参数的实现机制是完 ...
- Python基础之函数的闭包与装饰器的介绍
1.闭包的概念: 如果在一个函数中,定义了另外一个函数,并且那个函数使用了外面函数的变量,并且外面那个函数返回了里面这个函数的引用,那么称为里面的这个函数为闭包. 2.话不多说,以demo示例: de ...
- python基础(三)闭包与装饰器
闭包(closure): 内嵌函数通过调用外部嵌套函数作用域内的变量,则这个内嵌函数就是闭包. 闭包必须满足三个条件: 必须有一个内嵌函数 内嵌函数必须引用外部嵌套函数中的变量 外部函数的返回值必须是 ...
- Python 简明教程 --- 22,Python 闭包与装饰器
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...
- 21.python中的闭包和装饰器
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...
随机推荐
- Mac系统如何编辑hosts文件
Mac系统如何编辑hosts文件 Hosts 是一个没有扩展名的系统文件,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系 统会首先 ...
- 深入.net(数据类型)
C#究竟为我们提供了哪些“数据类型”供我们使用?这些类型有什么样的“特征”? 数据类型的分类: --- 数据类型是存放数据的容器.那么我们就以它们“存放数据的方式”分类! 1.值类型:变量中直接存放着 ...
- 【代码笔记】iOS-读取一段文字
一,效果图. 二,工程图. 三,代码. RootViewController.m #import "RootViewController.h" @interface RootVie ...
- Android touch mode和focusableInTouchMode分析
首先我们来看看touch mode的定义.它是用户和手机进行交互时view层次结构的一个状态.它本身是很容易理解的, 代表了最近一次的交互是否是通过触摸屏发生的,因为在Android设备上还存在别的交 ...
- 让UILabel的文字顶部对齐
参考资料 http://stackoverflow.com/questions/1054558/how-do-i-vertically-align-text-within-a-uilabel 方法一 ...
- 关于NodeJS的思考
对于NodeJS来说传统程序员比较陌生,初看以为是什么前端框架,其实并不是前端框架.传统的Javascript只能跑在浏览器中,但是一位叫Ryan Dahl的开发者灵感一来,为什么Javascript ...
- WPF学习之路(十二)控件(Items控件)
ListBox 提供了一个选项列表,可以固定或者动态绑定 <StackPanel> <GroupBox Margin="> <GroupBox.Header& ...
- WPF学习之路(二) XAML(续)
属性 简单属性 前面用到的Width/Height都是简单属性,其赋值一定要放到双引号里 XAML解析器会根据属性的类型执行隐式转换 与C#的区别 SolidBrush.Color = Colors. ...
- iBatis 中 Like 的写法实现模糊查询
iBatis 开发指南告诉我们,当 Person 对象的 name 属性不为 null 时启用 name 查询条件在映射文件 person.xml 中的配置为 <select id=" ...
- vmware 10 e1000e e1000e_cyclecounter_read 挂机解法
http://ehc.ac/p/e1000/mailman/message/34100875/In the e1000e_cyclecounter_read function, if incvalue ...