Python之路【第十七篇】:装饰器

写代码的时候有一个原则,开放封闭原则(面向对象):对某些东西开放,对某些封闭,在装饰器这里,函数内部是封闭的,不允许改变函数的内部。

装饰器用来装饰函数,可以让函数在执行之前或者执行之后,做一些操作,让函数调用者的操作不变,就能在执行前后做一些操作。简单来说,装饰器感觉就类似于装修,提供一些额外的功能。

装饰器的本质就是将原函数封装到另一个函数里面。

装饰器原理剖析

关键点1

def f1():print('1')
def f1():print('2')
f1()

上面这段函数执行后,输出的结果为2,因为python解释器从上往下执行,先把第一个f1放进内存,碰到第二个f1函数后又把它放进内存,所以f1指的是第二个函数的内容。

关键点2

@符号:

    @符号具有特殊性,@函数名,碰到后,先执行函数,并且将其下面的函数名当作参数,如:

def outer(func):pass
@outer
def f1():pass
def f2():pass

碰到@outer之后,先执行outer函数,然后将f1作为参数,此时func=f1(原来的f1函数)

outer的返回值赋值给f1,此时f1=outer返回值,所以以后再执行f1,就执行新的f1函数

 关键点3

只要函数用了装饰器,函数就会重新定义为装饰器的内层函数,所以如果函数有参数的话,装饰器的内层函数也要有相应的参数来接收,即inner函数要有相应的参数,同时,func函数等于原来的函数,所以func函数也要有相应的参数

inner(*args,**kwargs)

ret  = func(*args,**kwargs)

以后写装饰器就按照上面的写法来,这样就不用担心参数的问题了,碉堡了。

装饰器例子:

#!/usr/bin/env python
# -*- coding:utf-8 -*-def outer(func):def inner(*args,**kwargs):print('')ret = func(*args,**kwargs)print('')return retreturn inner@outer
def f1(a1):print('aa')return a1@outer
def f2(s1,s2):print('bb')return s1,s2ret1 = f1(1)ret2 = f2(2,3)print(ret1,ret2)

上面的程序输出结果为:


aa


bb

1 (2, 3)

可以看到,在不改变函数的基础上,函数执行了一些别的操作。上面这是一个装饰器装饰一个或多个函数的场景

多个装饰器装饰一个函数

#!/usr/bin/env python
# -*- coding:utf-8 -*-def outer0(func):def inner(*args,**kwargs):print('before')ret = func(*args,**kwargs)print('after')return retreturn inner
def outer(func):def inner(*args,**kwargs):print('')ret = func(*args,**kwargs)print('')return retreturn inner
@outer0
@outer
def f1():print('self')return None
f1()

输出结果为:

before

self

after

可以这样理解:

#part1
#一个新的函数,不妨叫这个函数为index
@outer
def f1():print('self')return None

然后代码就变成了下面这样:

#part2
@outer0 def index():pass

最后函数的执行顺序是这样的:先执行最外层的part2,即先输出before,在执行index函数,最后输出after,执行index函数的时候,就是执行part1,先输出'你',在输出'self',再输出'好'。

转载于:https://www.cnblogs.com/ronghe/p/8681358.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HALCON示例程序measure_chip.hdev芯片封装检测

HALCON示例程序measure_chip.hdev芯片封装检测 示例程序源码(加注释) 关于显示类函数解释 dev_update_off () read_image (Image, ‘die_on_chip’) get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width * 2, He…

工业机器人智能发展:视觉和触觉感应简化

机器人工业协会(Robotic Industries Association)指出,从2003到2005年间,北美机器人工业以20%的平均年增长率发展。在汽车市场需求疲软以及外国厂商的压力不断增加的背景下,这一成就是如何取得的?成本的普遍…

ASP站点无法访问怎么办

确保启用了目录浏览功能 转载于:https://www.cnblogs.com/acetaohai123/p/6571257.html

五、案例-指令参考-freemarker指令、表达式

案例-指令参考描述&#xff1a;本人自己测试写了一遍&#xff0c;如有错的地方&#xff0c;懂freemarker的朋友望指点指点&#xff01; 案例-指令参考 表达式 一、 Assign 1、<#assign name1"北京" name2"上海" name3"广东"> 调用&#xf…

PartitionMotionSearch()函数

encode_one_macroblock()函数中的运动估计分为两大块&#xff0c;对于宏块级的三种模式&#xff0c;分块后直接对patition依次调用PartitionMotionSearch()函数&#xff1b;而对于亚宏块级的&#xff08;含8x8, 8x4,4x8,4x4&#xff09;模式&#xff0c;首先将宏块拆分为4个88子…

201521123017 《Java程序设计》第4周学习总结

1. 本周学习总结 2. 书面作业 Q1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释&#xff0c;并在Eclipse中查看。(截图) Q2.面向对象设计(大作业1&#xff0c;非常重要) 2.1 将在网上商城购物或者在班级博客进行学习这一过程&#xff0c;描述成一个故事。…

完整的VAL3程序

start() begin//延时10秒 delay(5)//初始化变量call init()//清空原有运动堆栈resetMotion()//建立上电任务taskCreate "robotpower",100,robotpower()wait(isPowered())//建立生产任务taskCreate "ProductionCycle",10,ProductionCycle()//建立安全区域…

iOS WebView 加载本地资源(图片,文件等)

NSString *path [[NSBundle mainBundle] pathForResource:"关于.docx" ofType:nil]; NSURL *url [NSURL fileURLWithPath:path]; NSLog("%", [self mimeType:url]); //webview加载本地文件&#xff0c;可以使用加载数据的方式 //第一个诶参数是一个N…

本文以H264视频流为例,讲解解码流数据的步骤。

本文以H264视频流为例&#xff0c;讲解解码流数据的步骤。 为突出重点&#xff0c;本文只专注于讨论解码视频流数据&#xff0c;不涉及其它&#xff08;如开发环境的配置等&#xff09;。如果您需要这方面的信息&#xff0c;请和我联系。 准备变量 定义AVCodecContext。如…

2008-2021年商业银行数据(农商行、城商行、国有行、股份制银行)

2008-2021年商业银行数据&#xff08;农商行、城商行、国有行、股份制银行&#xff09; 1、时间&#xff1a;2008-2021年 2、范围&#xff1a;1700银行 3 、指标&#xff1a;证券简称、year、证券代码、资产总计、负债合计、所有者权益合计、利润总额、净利润、贷款总额、存…

EPSON 任务同步 改写

有时需要在多个任务执行之前来使它们同步。如果预先知道执行每项任务所需要的时间&#xff0c;它们就可以通过简单地等待由最慢的任务产生的信号来实现同步。然而&#xff0c;如果不知道那个任务是最慢的&#xff0c;就需要使用一个更复杂的同步化机制&#xff0c;如下所示VAL …

线程池的简单使用

创建指定线程数量的线程池 private static ExecutorService scheduledTaskFactoryExecutor null;private boolean isCancled false;private static class ThreadFactoryTest implements ThreadFactory { Overridepublic Thread newThread(Runnable r) { Thread threa…

异常--自定义异常类

为什么要调用父类构造器? http://blog.csdn.net/rockpk008/article/details/52951856 转载于:https://www.cnblogs.com/dwj-ngu/p/6576382.html

利用ffmpeg来进行视频解码的完整示例代码

&#xff08;转&#xff09;利用ffmpeg来进行视频解码的完整示例代码&#xff08;H.264&#xff09; Decode() { FILE * inpf; int nWrite; int i,p; int nalLen; unsigned char * Buf; int got_picture, consumed_bytes; unsigned char *DisplayBuf; Displ…

安卓观看免费视频

http://www.imooc.com/search/course?wordsAndroid%E6%94%BB%E5%9F%8E%E7%8B%AE%E7%AC%AC%E4%B8%80%E8%AF%BE&page3 http://www.imooc.com/course/list?candroid&src360onebox http://www.bilibili.com/video/av2788563/index_4.html http://www.imooc.com/course/pr…

EtherCAT 网站链接

http://www.ethercat.org.cn/cn.htm EtherCAT技术介绍 EtherCAT系统组成和工作原理 EtherCAT采用主从式结构&#xff0c;主站PC机采用标准的100Base-TX以太网卡&#xff0c;从站采用专用芯片。系统控制周期由主站发起&#xff0c;主站发出下行电报&#xff0c;电报的最大有效数…

IEC 6-1131/3的5种标准编程语言

用于开发控制系统和商业管理系统的TRACE MODE6编程工具面向不同领域的软件工程师. TRACE MODE6包含的五种编程语言为&#xff1a;Techno SFC、Techno LD、Techno FBD、Techno ST和Techno IL. 这些语言是下列IEC 6-1131/3标准语言的扩展&#xff1a; SFC&#xff08;顺序功能图…

ngRx 官方示例分析 - 4.pages

Page 中通过构造函数注入 Store&#xff0c;基于 Store 进行数据操作。 注意 Component 使用了 changeDetection: ChangeDetectionStrategy.OnPush. OnPush means that the change detectors mode will be set to CheckOnce during hydration. /app/containers/collection-page…

用ffmpeg把yuv格式转化为mpeg格式

http://blog.sina.com.cn/s/blog_5f5ad6a90100cs5k.html

方法:查询MongoDB数据库中最新一条数据(JAVA)

使用JAVA语言查询MongoDB中某个数据库某个集合的最新一条数据&#xff1a; MongoCollection<Document> cpu MongoClient.getDatabase("sysmgr").getCollection("cpu"); //获取所需集合 Document dbo cpu.find().sort(descending("time"…