装饰器分步解释-形成过程:

#-*- 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 )的更多相关文章

  1. Python装饰器基础及运行时间

    一.装饰器基础 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数).装饰器可能会处理被装饰的函数,然后把他返回,或者将其替换成另一个函数或可调用对象. eg:decorate装饰器 @decor ...

  2. 回顾Python装饰器

    函数装饰器(function decorator)可以对函数进行“标注”,给函数提供更多的特性. 在理解装饰器之前需要理解闭包(closure).Python3.0 引入了保留关键字 nonlocal ...

  3. Fluent_Python_Part3函数即对象,07-closure-decoration,闭包与装饰器

    第7章 函数装饰器和闭包 装饰器用于在源码中"标记"函数,动态地增强函数的行为. 了解装饰器前提是理解闭包. 闭包除了在装饰器中有用以外,还是回调式编程和函数式编程风格的基础. 1 ...

  4. python 装饰器(四):装饰器基础(三)叠放装饰器,参数化装饰器

    叠放装饰器 示例 7-19 演示了叠放装饰器的方式:@lru_cache 应用到 @clock 装饰fibonacci 得到的结果上.在示例 7-21 中,模块中最后一个函数应用了两个 @htmliz ...

  5. Python函数装饰器高级用法

    在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...

  6. Java设计模式(七)Decorate装饰器模式

    一.场景描述 (一)问题 系统中最初使用Crystal Report(水晶报表)工具生成报表,并将报表发送给客户端查看,此时定义一CrystalReport工具类即可完成水晶报表的生成工作. 后续报表 ...

  7. python cookbook 学习系列(一) python中的装饰器

    简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...

  8. 循序渐进Python3(四) -- 装饰器、迭代器和生成器

    初识装饰器(decorator ) Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法 ...

  9. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

随机推荐

  1. 四大组件之Service

    1 通过startService 1.1 与调用者相对独立,没有返回,用于播放音乐,下载文件 1.2 如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行.下次 ...

  2. 《LeetBook》leetcode题解(8): String to Integer (atoi) [E]——正负号处理

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  3. @SafeVarargs注解

    被@SafeVarargs注解标注的方法必须是由static或者final修饰的方法. 使用泛型的变长参数方法产生编译器警告的示例: public static <T> T useVara ...

  4. unity 优化之overdraw查看

    scene视图里面能直接看,打开左上角那个下拉选项,选择overdraw就行 转载篇在game视图下查看overdraw:       https://blog.csdn.net/complicate ...

  5. AES加密的四种模式详解

    对称加密和分组加密中的四种模式(ECB.CBC.CFB.OFB) 一. AES对称加密:                                                       A ...

  6. Struts2 Validate

    1.自定义action继承ActionSupport 2.复写validate方法,因为ActionSupport实现了Validate这个借口,而这个借口中定义了validate方法 3.当请求时, ...

  7. C#调用Dll文件中方法的简单应用

    参考:http://www.cnblogs.com/Asuphy/p/4206623.html 直接看代码,最简单的引入,只需要3步: using System; using System.Colle ...

  8. java注释详解--javadoc注释

    一. Java注释分类// 注释一行 /* ...... */ 注释若干行 /** ...... */ 注释若干行,并写入 javadoc 文档 通常这种注释的多行写法如下: /** * ...... ...

  9. 【转】MVC Model建模及Entity Framework Power Tool使用

    MVC如使用Code-First代码优先约定,先建实体类,再根据实体类创建数据库. 在创建实体类后,新建一个数据上下文类,如下: publicclassMusicStoreDB : DbContext ...

  10. Java大法之面向对象

    总觉得要写点东西,写写自己对知识的理解,对自己学的东西是否编程自己的了.我在想,如果让自己用自己的语言来解释,什么是面向对象,我可能会愣一下,我问自己什么是面向对象的时候,我想了想,自言自语说:面向对 ...