您的位置:首页 > 编程语言 > Python开发

python学习笔记-Day04-第四部分(装饰器)

2015-11-21 10:19 585 查看
这周学到了python的装饰器,以前没有接触过,问了一个搞php开发的同事什么是装饰器,他说就好像构造函数一样,可惜我已经把构造函数忘得光光了,想不起来是啥了。现在就找资料了解了解。毕竟装饰器是一个不用也能实现程序的功能,但是用了装饰器以后会显得你的技术特NB,但是不太好理解

学装饰器之前,需要先了解一下函数,前面的笔记里,有写过函数相关的笔记,可以先去参考一下前面的文章,这里只简单说一下。
在python中,函数由 def 关键字,函数名,可选的参数列表和函数体 来组成,通过return语句来返回值,如果没有return语句的时候,函数自动返回一个None值,

装饰器其实就是把一个函数当做参数,然后返回一个替代版的函数,
def wrapper(a_fun):
def fun():
print "a fun"
tmp = a_fun()
return tmp +1
return fun

def w_test():
return 1

var1 = wrapper(w_test)
print var1()   #1
print w_test()
输出:
a fun # var1() 输出
2 # var1() 输出
1 # w_test() 输出

上面是一个装饰器的例子,我们定义了一个函数 wrapper() ,参数为一个名叫a_fun的函数,在函数内部定义了一个嵌套的函数 fun() 。fun() 会输出一串字符串,然后调用 a_fun(), tmp 可以得到a_fun()的返回值, wrapper每次调用 fun() 的时候值可能会不一样(如果使用的是其他函数),但是不管a_fun()的返回值 是什么,外面都会调用它,最后 fun() 的返回值为 a_fun()+1 。 在位置 #1处,我们调用存储在变量var1 里面的函数,可以得到打印出的字符串和返回值 2,而不是函数 w_test() 的返回值

我们可以认为 var1 是函数 w_test() 的一个装饰版本,或者说一个改造版本,而且并没有对原来的函数w_test() 进行任何改变。 写一个装饰器的话,外面可以用装饰版本 完全替换掉原来的函数w_test(),这样就可以得到一个 改造版 的函数w_test() , 在使用过程中 ,还不需要学习新的语法,只要简单的给变量复制就可以达到效果

w_test = wrapper(w_test)
w_test
输出:
<function fun at 0x7f5edf6c5668>
执行上面的代码后,外面再怎么调用都不会牵扯原来的函数w_test(),调用的会是改造版本的w_test()

再来一个具体的例子.

使用 @ 标识符 将装饰器应用到函数
python2.4 支持使用标识符讲装饰器应用到函数上,只需要在函数的定义钱叫上@和装饰器的名称,
上面的例子中,外面使用的方法是

foo = wrapper(foo)
这种方法可以在任何时候对任意的方法进行包装,但是代码写的多,累啊。我们可以使用简单的方法,使用@装饰,将上面的例子修改后:
wrapper(func):
result():
func()
result

@foo():
foo()
需要记住的是, 使用 foo = wrapper(foo) 和在函数前加 @wrapper 这两种方法是一样的,python只是增加了一些语法糖 ,让装饰的行为更加直接明确和优雅,说白了 就是让你更容易看代码。

关于传递参数
上面我们已经完成了一个装饰器,但是这个装饰器只能应用在一类具体的方法上。如果我们想要实现一个能够应用在任何方法的装饰器上要怎么做呢?

其实可以猜出来一部分 使用*args 和 **kwargs。
例:
first(*args):
args

first()
first(,,)
lst = [,,,]
first(*lst)
上面定义了函数 first ,将任何传递进来的参数打印, * 表示 调用的方法的时候,额外的参数可以从一个可迭代的列表中获得,或者是 定义方法的时候 表示这个参数可以接收任意数量的位置参数

** 比* 稍微复杂一点点, 使用**的时候,表示与其对应的是一个代表着键值对的参数字典。
例:
sec(**kwargs):
kwargs

dic = {:,:}
sec()
sec(=,=)
sec(**dic)


让我们来写一个功能更强大的装饰器
war(func):
in_war(*args,**kwargs):
%(args,kwargs)

in_war

@foo_1(x,y=):
x+y

@foo_2():
foo_1(,)
foo_1()
foo_2()

http://timesnotes.blog.51cto.com/1079212/1715330 http://www.timesnotes.com/?p=111

本文出自 “Will的笔记” 博客,请务必保留此出处http://timesnotes.blog.51cto.com/1079212/1715330
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: