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

python 装饰器

2015-03-26 15:34 260 查看

装饰器研究

装饰器种类

装饰器分为两类,一种是不需要参数的装饰器,另一种需要带参数。

下面展示一个不带参数的装饰器,实现简单的类似AOP功能,记录函数运行时间,或者记录日志等。

def running_time(func):
@functools.wraps(func)  #备注
def wrapper(*args, **kw):
start_time = time.time()
ret = func(*args, **kw)
end_time = time.time()
print '[{0}()] done, run time : {1} sec'.format(func.__name__, end_time - start_time)
return ret
return wrapper

@running_time
def nothing():
for x in xrange(10):
print "Maybe YJ ,have a try"


对于带参数的装饰器,需要进行二级封装,在上面装饰器的基础上,在封装一层。示例代码如下:

def mydecorator(arg1, arg2):
def _mydecorator(function):
def __mydecorator(*args, **kw):
# 借助参数做些什么事情
res = function(*args, **kw)
return res
return __mydecorator()
return _mydecorator


注意functools.wraps()函数的作用:调用经过装饰的函数,相当于调用一个新函数,那查看函数参数,注释,甚至函数名的时候,就只能看到装饰器的相关信息,被包装函数的信息被丢掉了。而wraps则可以帮你转移这些信息。

f = running_time(nothing)
print f.__name_


输出结果会应为wraps包装而不同。

装饰器应用

除了前面介绍可以用于日志,运行时间等记录外。还有一些应用。

1 . 用来实现单例模式:

def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton

@singleton
class MyClass4(object):
a = 1
def __init__(self, x=0):
self.x = x

one = MyClass4()
two = MyClass4()
print id(one)
print id(two)


2 . 实现函数静态属性的注入

def static_var(**kwargs):
def decorate(func):
for varname, value in kwargs.iteritems():
setattr(func, varname, value)
return func
return decorate

@static_var(age=12)
def struggle2(number):
print number
print struggle2.age
struggle2.age += 1
struggle2(222)


这个静态属性,与全局变量不同,是函数专享的。

3 . 还有比如 参数检查,缓存, 代理,上下文提供者等应用。暂时没有使用经验。大概使用的情况都差不多。还是很实用的技术。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  装饰器-python