装饰器( decorate )
装饰器分步解释-形成过程:
#-*- coding: UTF-8 -*- #示例1:
def deco(p_args):
def pack():
print('haha,i am deco fun')
print('i want to use parent fun arg: '+p_args)
print('haha,i am deco fun--finished\n')
return pack deco('abc') #执行结果无返回值
deco('abc')() #执行结果同示例2 #示例2:
def deco(p_args):
def pack():
print('haha,i am deco fun')
print('i want to use parent fun arg: '+p_args)
print('haha,i am deco fun--finished\n')
return pack() #需要加上小括号,否则pack函数不会被执行 deco('abc') #执行结果返回如下:
#haha,i am deco fun
#there are 2 args.they are:
#haha,i am deco fun--finished #示例3:
def myf():
print('i want to be decorated.') def deco(fun):
def pack():
print('haha,i am deco fun')
#print('i want to use parent fun arg: '+p_args)
fun()
print('haha,i am deco fun--finished\n')
return pack #此处不加括号,deco(myf)执行结果无返回。同示例1 deco(myf) #执行结果无返回。
deco(myf)() #执行结果同示例4 #示例4:
def myf():
print('i want to be decorated.') def deco(fun):
def pack():
print('haha,i am deco fun')
#print('i want to use parent fun arg: '+p_args)
fun()
print('haha,i am deco fun--finished\n')
return pack() #加括号,deco(myf)执行结果输出如下,同示例2 deco(myf) #将myf函数传给deco函数的参数fun。
#haha,i am deco fun
#i want to be decorated.
#haha,i am deco fun--finished #示例5:
def myf():
print('i want to be decorated.') def deco(fun):
def pack():
print('haha,i am deco fun')
#print('i want to use parent fun arg: '+p_args)
fun()
print('haha,i am deco fun--finished\n')
return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如deco(myf)() #deco(myf)()的执行结果等价于如下,输出结果同示例4:
myf1 = deco(myf)
myf1()
#haha,i am deco fun
#i want to be decorated.
#haha,i am deco fun--finished #此处的变量myf1跟myf没有任何关系,只是将deco(myf)这个函数赋予了变量myf1,然后再通过myf1()的方式执行该函数。所以可以将myf1重新写为myf,就成了装饰器的效果,如示例6。
myf = deco(myf)
myf() #示例6--装饰器:
def deco(fun):
def pack():
print('haha,i am deco fun----')
#print('i want to use parent fun arg: '+p_args)
fun()
print('haha,i am deco fun--finished\n')
return pack #此处不加括号,而是在最外面的函数执行的时候再加括号执行,如deco(myf)() @deco
def myf():
print('i want to be decorated,6.')
myf()
装饰器中的函数参数传递:
def deco(fun):
def pack(*args,**kwargs): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。
print('haha,i am deco fun')
print('there are %d args.they are: %s %d' %(len(args),args[0],args[1])) #调用原函数的参数
fun(*args,**kwargs)
print('haha,i am deco fun--finished')
return pack @deco #将sayhi传给deco的参数fun
def sayhi(name,age):
print('helo,i am %s ,my age is %d.'%(name,age)) sayhi('LiuXue',20)
#返回结果:
haha,i am deco fun
there are 2 args.they are: LiuXue 20
helo,i am LiuXue ,my age is.
haha,i am deco fun--finished
#定义函数:
def hello(*args,**kw):
print 'ab'
print args
print kw
args=range(1,5) hello(args) #返回值:
ab
([1, 2, 3, 4],)
{} #定义装饰函数:
def dec(fun):
def wrapper(*args,**kw):
print 'do sth. before'
fun(*args,**kw)
print 'do sth. after'
return wrapper dec(hello(args)) #将hello函数及参数当做变量赋予dec,只相当于直接执行hello(args),返回值:
ab
([1, 2, 3, 4],)
{} p=dec(hello)
p(args) dec(hello)(args) #将函数当做变量赋予dec,然后通过变量调用函数,再赋予变量变量,返回值:
do sth. before
ab
([1, 2, 3, 4],)
{}
do sth. after
def dec(fun):
def wrapper(*args,**kw):
print 'do sth. before'
fun(*args,**kw) #此处如果改为 return fun(*args,**kw),则下一句print 'after'不会再执行。在函数中,遇到第一个return则不会再执行后面的语句,如果返回两个值,可以写在同一行。如果用了return,函数执行完会得到结果,没有return则无返回值
print 'do sth. after'
return wrapper @dec #通过@调用装饰函数
def hello(*args,**kw):
print 'ab'
print args
print kw
args=range(1,5) hello(args)
装饰器自身接收参数:
# -*- coding: UTF-8 -*- def deco(darg): #装饰函数的参数
print darg
def getFun(func):
def pack(name,age): #这样写可以传递任意参数。也可以直接写name,age,只是这样在其他函数调用的时候会出错,因为其他函数的参数可能并不是name,age等。。。
print('haha,i am darg: '+darg) #装饰函数的参数可以传入使用
print('there are args.they are: %s %d' %(name,age)) #调用原函数的参数
func(name,age)
print('haha,i am deco fun--finished')
return pack
return getFun @deco('abc') #装饰函数调用参数‘abc’
def sayhi(name,age):
m=15
print('helo,i am %s ,my age is %d.'%(name,age)) name='LiuXue'
age=20
sayhi(name,age)
# #返回结果:
abc
haha,i am darg: abc
there are args.they are: LiuXue 20
helo,i am LiuXue ,my age is 20.
haha,i am deco fun--finished
装饰器( decorate )的更多相关文章
- Python装饰器基础及运行时间
一.装饰器基础 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数).装饰器可能会处理被装饰的函数,然后把他返回,或者将其替换成另一个函数或可调用对象. eg:decorate装饰器 @decor ...
- 回顾Python装饰器
函数装饰器(function decorator)可以对函数进行“标注”,给函数提供更多的特性. 在理解装饰器之前需要理解闭包(closure).Python3.0 引入了保留关键字 nonlocal ...
- Fluent_Python_Part3函数即对象,07-closure-decoration,闭包与装饰器
第7章 函数装饰器和闭包 装饰器用于在源码中"标记"函数,动态地增强函数的行为. 了解装饰器前提是理解闭包. 闭包除了在装饰器中有用以外,还是回调式编程和函数式编程风格的基础. 1 ...
- python 装饰器(四):装饰器基础(三)叠放装饰器,参数化装饰器
叠放装饰器 示例 7-19 演示了叠放装饰器的方式:@lru_cache 应用到 @clock 装饰fibonacci 得到的结果上.在示例 7-21 中,模块中最后一个函数应用了两个 @htmliz ...
- Python函数装饰器高级用法
在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...
- Java设计模式(七)Decorate装饰器模式
一.场景描述 (一)问题 系统中最初使用Crystal Report(水晶报表)工具生成报表,并将报表发送给客户端查看,此时定义一CrystalReport工具类即可完成水晶报表的生成工作. 后续报表 ...
- python cookbook 学习系列(一) python中的装饰器
简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...
- 循序渐进Python3(四) -- 装饰器、迭代器和生成器
初识装饰器(decorator ) Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法 ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
随机推荐
- 浅谈js中的垃圾两种回收机制
一.标记清除 标记清除的主要思想是先建立各个对象的关联,然后从根节点出发,使用广度优先搜索依次标记所有对象,那些不能被标记的对象就应该作为垃圾回收. 这种方式的主要缺点就是如果某些对象被清理后,内存是 ...
- 基于libcurl实现REST风格http/https的get和post
c/c++开发中经常要用到http/https协议,直接使用socket工作量很大,要是使用socket实现https,那更不可思议,开源的c/c++的http客户端框架,libcurl是首选,而且也 ...
- [转]Hadoop集群_WordCount运行详解--MapReduce编程模型
Hadoop集群_WordCount运行详解--MapReduce编程模型 下面这篇文章写得非常好,有利于初学mapreduce的入门 http://www.nosqldb.cn/1369099810 ...
- Java 实现两个整数变量的交换
class OperatorTest { public static void main(String[] args) { int a = 10; int b = 20; System.out.pri ...
- 证书透明度Certificate Transparency
发现使用google浏览器访问HTTPS网址时,点击小锁-->>连接-->>有一项服务器未提供任何 certificate transparency 信息?只有google浏览 ...
- [转]log4net 发布到生产环境不写日志的解决方法--使用 NLog日志
本文转自:http://www.cnblogs.com/weiweictgu/p/5848805.html 1.升级到log4net的最新版 PM下执行 Install-Package log4net ...
- C# 之程序退出的方法
1.this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出: 2.Application.Exit(); 强制所有消息中 ...
- android 模拟器无法启动问题
很早之前就碰到过Android Studio模拟器无法启动的问题,今天终于尝试去解决了下,下面将我解决的方法记录下. 模拟器报错信息为: emulator: ERROR: x86 emulation ...
- groovy实现循环、交换变量、多赋值、?.运算符
/** * Created by Jxy on 2019/1/3 10:01 * 1.实现循环的方式 * 2.安全导航操作符---?. * 3.一次性赋值给多个变量 */ 0.upto(2){ pri ...
- K:二叉查找树(BST)
相关介绍: 二叉查找树(英语:Binary Search Tree),也称二叉搜索树.有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tre ...