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

Python装饰器学习笔记

2015-05-31 00:00 691 查看
摘要: 简单的python装饰器介绍

之前在看<<Python核心编程>>时遇到decorator时看得云里雾里,然后也没去多管,想到等以后遇到这个问题 时再去解决。今天在看Django代码时看到login_required等装饰器时又遇到这个东西了,于是在网上找了一些文档重新学了一下,在此做一个 总结。

1. 装饰器含义

装 饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器, 我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

2. 装饰器语法

(1)无参数装饰器

def deco(func):

print("deco")

return func

@deco

def foo():

print("foo")

foo()

第一个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(记住一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo)

(2)有参数装饰器

被装饰函数无参数

def deco(argv):

def decorator(func):

print("decorator")

return func

print("deco")

print(argv)

return decorator

@deco ("123")

def foo():

print("foo")

foo()

第一个函数deco是装饰函数,它的参数是用来“加强装饰”的。由于此函数并非被装饰的函数对象,所以在内部必须至少创建一个接受被装饰函数的函数,然后返回这个对象。实际上此时foo = deco(argv)(foo)

被装饰函数也有参数

from functools import wraps

def deco(argv):

def decorator(func):

@wraps(func)

def wrapper(*args, **kwargs):

print("wrapper")

return func(*args, **kwargs)

print("decorator")

return wrapper

print("deco")

print(argv)

return decorator

@deco ("123")

def foo(data):

"this is foo"

print("foo")

print(data)

foo("afdasdf")

print(foo.__name__, foo.__doc__)

在decorator函数内部还需要定义一个函数来接受被装饰函数的参数。此时foo = deco(argv)(foo)(data)

首 先注意第5行,如果注释这一行,foo.__name__将是'wrapper',使用这个装饰器后装饰之后的foo.__name__将还是原来的 foo,wraps装饰器是将func的常用属性赋给了wrapper函数。另外相信你也注意到了,这个装饰器竟然带有一个参数。实际上,他还有另外两个 可选的参数,assigned中的属性名将使用赋值的方式替换,而updated中的属性名将使用update的方式合并,你可以通过查看 functools的源代码获得它们的默认值。对于这个装饰器,相当于wrapper = functools.wraps(func)(wrapper)

(3)多装饰器组合使用

def deco1(func):

print("deco1")

return func

def deco2(func):

print("deco2")

return func

@deco2

@deco1

def foo():

print("foo")

foo()

注意多个装饰器的执行顺序,应该是先执行下面的,然后是上面的。这里应先执行deco1,然后是deco2。

(4)例子

def makebold(func):

def wrapped():

return "<b>" + func() + "</b>"

return wrapped

def makeitalic(func):

def wrapped():

return "<i>" + func() + "</i>"

return wrapped

@makebold

@makeitalic

def say():

return "Hello"

print(say())

#output

'''''

<b><i>Hello</i></b>

'''

3. 体会

当多个函数有重复代码时可以将此部分代码单独拿出来整理成一个装饰器,然后对每个函数调用该装饰器,这样可以实现代码的复用,而且可以让原来的函数更轻便。

还有就是当我们需要为多个已经写好的函数添加一个共同功能,比如检查参数的合法性。我们就可以单独写一个检查合法性的装饰器,然后在每个需要检查参数合法性的函数出调用即可,而不用去每个函数内部修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python decorator 装饰器