Python的高级特性7:闭包和装饰器

时间:2022-10-22 23:02:15

本节跟第三节关系密切,最好放在一起来看: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:闭包和装饰器的更多相关文章

  1. 13、python中的函数(闭包与装饰器)

    一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...

  2. python 生成器,迭代器,闭包,装饰器

    1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...

  3. Python虚拟机函数机制之闭包和装饰器(七)

    函数中局部变量的访问 在完成了对函数参数的剖析后,我们再来看看,在Python中,函数的局部变量时如何实现的.前面提到过,函数参数也是一种局部变量.所以,其实局部变量的实现机制与函数参数的实现机制是完 ...

  4. Python基础之函数的闭包与装饰器的介绍

    1.闭包的概念: 如果在一个函数中,定义了另外一个函数,并且那个函数使用了外面函数的变量,并且外面那个函数返回了里面这个函数的引用,那么称为里面的这个函数为闭包. 2.话不多说,以demo示例: de ...

  5. python基础(三)闭包与装饰器

    闭包(closure): 内嵌函数通过调用外部嵌套函数作用域内的变量,则这个内嵌函数就是闭包. 闭包必须满足三个条件: 必须有一个内嵌函数 内嵌函数必须引用外部嵌套函数中的变量 外部函数的返回值必须是 ...

  6. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  7. 21.python中的闭包和装饰器

    python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...

  8. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...

  9. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...

随机推荐

  1. python 之 PIP 安装

    1.安装的必备包 pip 和 setuptool 都要有, 这个可以从python.org网站下载 //  setuptool 安装  下载地址 https://pan.baidu.com/s/1gf ...

  2. PHP的继承方法如何获取子类名?get_class() 和 get_called_class()

    PHP里的__CLASS__这类东西是静态绑定的,如果不在子类里重载的话,那么继承父类方法所得到的依旧是父类的名称,而不是子类的名称,比如: <?php class A { function _ ...

  3. structs环境搭建

    (1)<s:fielderror />放在JSP中,如果没在web.xml中配置filter相关内容,会有The Struts dispatcher cannot be found.从而显 ...

  4. 【HDU 1009】FatMouse&&num;39&semi; Trade

    题 Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the ware ...

  5. nginx优化之请求直接返回json数据

    对于有些服务端接口返回是固定值的json,可通过配置nginx直接返回json,减少程序的加载对资源的占用,减少接口响应时间 location ~* (request/update)$ {     d ...

  6. Javascript 设计模式 辛格尔顿

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/30490955 我一直很喜欢Js,,,今天写JsSingleton模式来实现,以及 ...

  7. 【原创101】Servlet精细笔记

    一.什么Servlet? servlet 是运行在 Web 服务器中的小型 Java 程序(即:服务器端的小应用程序).servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户 ...

  8. Selenium实现的技巧

    截图功能:    try { File srcFile = ((TakesScreenshot)dr).getScreenshotAs(OutputType.FILE);                ...

  9. SDP(7):Cassandra- Cassandra-Engine:Streaming

    akka在alpakka工具包里提供了对cassandra数据库的streaming功能.简单来讲就是用一个CQL-statement读取cassandra数据并产生akka-stream的Sourc ...

  10. Java堆和栈的区别和介绍,JVM的堆和栈

    一.Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存.   堆:主要用于存储实例化的对象,数组.由JVM动态分配内存空间.一个JVM只有一个堆内存,线程是可以共享数据的. ...