编写自定义装饰器有许多方法,但最简单和最容易理解的方法是编写一个函数,返回封装原始函数调用的一个子函数。 通用的模式如下。
python代码
def my_decorator(function):
def _my_decorator(*args, **kw):
#在调用实际函数之前做些填充工作
res = function(*args, **kw)
#做完某些填充工作之后
return res
#返回子函数
return _my_decorator
当装饰器需要参数时,必须使用第二级封装。
python代码
def my_decorator(arg1, arg2):
def _my_decorator(function):
def __my_decorator(*args, **kw):
res = function()
return res
return __my_decorator
return _my_decorator
引用
因为装饰器在模块第一次被读取时由解释程序装入,所以它们的使用必须受限于总体上可以应用的封装器。如果装饰器与方法的类或所增强的函数签名绑定,它应该被重构为常规的可调用对象,从而避免复杂性。在任何情况下,当装饰器处理api时,一个好的方法是将它们聚集在一个易于维护的模块中。
参数检查:
python代码
def check_param_isvalid():
def check(method):
def check_param(*args,**kwargs):
for a in args:
assert isinstance(a, int),”arg %r does not match %s” % (a,int)
assert a > 100000,”arg %r must gt 100000″ % a
return method(*args, **kwargs)
return check_param
return check
@check_param_isvalid()
def foo(*args):
print args
foo(200000,500000)
缓存:
python代码
import time
import hashlib
import pickle
cache = {}
def is_obsolete(entry, duration):
return time.time() – entry[‘time’] > duration
def computer_key(function, args, kw):
key = pickle.dumps((function.func_name, args, kw))
return hashlib.sha1(key).hexdigest()
def memoize(duration=30):
def _memoize(function):
def __memoize(*args, **kw):
key = computer_key(function, args, kw)
if key in cache and not is_obsolete(cache[key], duration):
print ‘wo got a winner’
return cache[key][‘value’]
result = function(*args, **kw)
cache[key] = {‘value’:result,’time’:time.time()}
return result
return __memoize
return _memoize
@memoize()
def very_complex_stuff(a,b):
return a + b
print very_complex_stuff(2,2)
代理:
python代码
class user(object):
def __init__(self, roles):
self.roles = roles
class unauthorized(exception):
pass
def protect(role):
def _protect(function):
def __protect(*args, **kw):
user = globals().get(‘user’)
if user is none or role not in user.roles:
raise unauthorized(“i won’t tell you”)
return function(*args, **kw)
return __protect
return _protect
tarek = user((‘admin’, ‘user’))
bill = user((‘user’,))
class mysecrets(object):
@protect(‘admin’)
def waffle_recipe(self):
print ‘use tons of butter!’
these_are = mysecrets()
user = tarek
these_are.waffle_recipe()
user = bill
these_are.waffle_recipe()
上下文提供者:
python代码
from threading import rlock
lock = rlock()
def synchronized(function):
def _synchronized(*args, **kw):
lock.acquire()
try:
return function(*args, **kw)
finally:
lock.release()
return _synchronized
@synchronized
def thread_safe():
print ‘haha’
thread_safe()