详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介绍的python装饰器就能够很好的解决这类问题.
1.闭包函数
闭包比较简单,直接上代码
def _Sum():
num1 = 1
num2 = 2 def count():
num3 = 3
return num1 + num2 + num3 # a: - 外部变量
return count
满足闭包的主要两点:函数内部定义的函数;引用了外部变量但非全局变量。
2.装饰器
有了闭包函数的概念,我们再去理解装饰器会相对容易一些。python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针)。装饰器函数的外部函数传入我要装饰的函数名字,返回经过修饰后函数的名字;内层函数(闭包)负责修饰被修饰函数。从上面这段描述中我们需要记住装饰器的几点属性,以便后面能更好的理解:
"""
装饰器
实质:就是一个函数
参数:是要被装饰的函数
返回:装饰完的函数名
作用:为已有的功能模块添加额外的功能
特点:不需要修改源码(源代码不做任何操作)
"""
2.1 函数装饰器
我们以为函数添加计时功能为例讲解
def Test(func):
print "Test parameter Pointer: %s" % func.__name__ def test(*args, **kwargs):
start_time = time.time()
func()
end_time = time.time()
print end_time-start_time return test @Test
def my_log():
time.sleep(0.8) my_log()
在上面的例子里,my_log是我要装饰器的函数,我们要给my_log函数添加程序运行计时的功能.@Test这个语法相当于 执行 my_log = Test(func), 为my_log函数装饰并返回对象指针。在装饰器函数Test中,该函数传入func参数(实质是被装饰函数my_log).在首次调用my_log()时,分俩步执行:1.先执行装饰器Test[类似于Test(my_log)],此时,func指向my_log所在的内存位置,而由于Test装饰器函数返回内置函数test,所以被装饰函数my_log指向内置函数test所在的内存位置.
2.当指行完装饰器函数后,调用my_log函数,此时的my_log函数实质是内置函数test,也就是调用了test(),从而在执行func()[即在此处才是真正调用了原函数my_log]函数.这就是一个简单装饰器的全部流程,主要的就是函数指针所指的内存位置发生变化.
执行结果:
类方法的函数装饰器 : 类方法的函数装饰器和函数的函数装饰器类似。
import time def decorator(func):
def wrapper(me_instance):
start_time = time.time()
func(me_instance)
end_time = time.time()
print(end_time - start_time)
return wrapper class Method(object): @decorator
def func(self):
time.sleep(0.8) p1 = Method()
对于类方法来说,都会有一个默认的参数self,它实际表示的是类的一个实例,所以在装饰器的内部函数wrapper也要传入一个参数 - me_instance就表示将类的实例p1传给wrapper,其他的用法都和函数装饰器相同。
2.2 类装饰器
前面我们提到的都是让 函数作为装饰器去装饰其他的函数或者方法,那么可不可以让 一个类发挥装饰器的作用呢?答案肯定是可以的,一切皆对象嚒,函数和类本质没有什么不一样。类的装饰器是什么样子的呢?
class Decorator(object):
def __init__(self, f):
self.f = f
def __call__(self):
print("decorator start")
self.f()
print("decorator end") @Decorator
def func():
print("func") func()
这里有注意的是:__call__()是一个特殊方法,它可将一个类实例变成一个可调用对象:
p = Decorator(func) # p是类Decorator的一个实例
p() # 实现了__call__()方法后,p可以被调用
部分代码事例来自:https://www.cnblogs.com/lianyingteng/p/7743876.html
详解Python闭包,装饰器及类装饰器的更多相关文章
- 详解python的装饰器decorator
装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- 详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...
- python 进阶篇 函数装饰器和类装饰器
函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...
- 详解 Python 的二元算术运算,为什么说减法只是语法糖?
原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...
- 详解python函数的参数
详解python函数的参数 一.参数的定义 1.函数的参数在哪里定义 在python中定义函数的时候,函数名后面的括号里就是用来定义参数的,如果有多个参数的话,那么参数之间直接用逗号, 隔开 案列: ...
- 详解Python 切片语法
Python的切片是特别常用的功能,主要用于对列表的元素取值.这篇文章主要介绍了详解Python 切片语法,需要的朋友可以参考下 Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片 ...
- 详解Python编程中基本的数学计算使用
详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...
- 详解Python中内置的NotImplemented类型的用法
它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...
随机推荐
- Go语言反射之反射调用
## 1 概述利用反射,不仅可以获取信息,还可以创建实例,执行函数和方法.就是反射代理执行. <!-- more -->## 2 创建实例创建实例的前提是具有 `reflect.Type` ...
- 20155217 《Java程序设计》第三次实验报告
20155217 <Java程序设计>第三次实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...
- 20155234java实验一
实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 1.没有Linux基础的同学建议先学习Linux基础入门(新版))Vim ...
- 每天一个linux命令(1):ln 命令
每天一个linux命令(35):ln 命令 ln 是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在 每一 ...
- Q&As:1.cocos2d-html5如何获得鼠标划过事件
不喜欢按部就班学东西,感觉各种框架各种技术就应该是拿到手用的,这应该是导致我现在学了这么多却没一样精通的缘故吧. 发现自己喜欢在QQ群回答一些菜鸟的问题,就算自己不清楚也会乐意看代码帮助解决╮(╯_╰ ...
- 通过dotnet命令行设置asp.net core服务的启动地址
需求: 通过dotnet命令行启动asp.net core 服务时,自定义监听端口. 方法: 在program.cs中增加命令行参数配置: WebHost.CreateDefaultBuilder(a ...
- T-SQL语句基础
连接服务器 - 去哪个仓库找目标数据库 - 找仓库中的目标区域查找目标表 - 找货柜找数据(以行为基础单位) - 在货柜上找到目标的物品 基础T-Sql语句1.SQL语句的注释 2.创建数据库crea ...
- info信息的获取
一.绝对路径(_SERVER[“SCRIPT_FILENAME”])这个是最常用,也是最有效的一个办法,找到phpinfo()页面可以直接找到网站的绝对路径,对于写shell和信息搜集是必不可少的.二 ...
- JMeter学习工具简单介绍
JMeter学习工具简单介绍 一.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序).它可以用来测试静态 ...
- JUC——ThreadFactory线程工厂类(四)
ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...