1.参数检查
检查函数接收或返回的参数,在特定的上下文执行可能有用。
def typeassert(in_ = () , out = (type(None) , )) :
def _typeassert(func):
def check_run_check(*args):
# 检查参数列表
if type(func).__name__ == 'method' :
checkable_args = args[1:] # 除去self
elif type(func).__name__ == 'function' :
checkable_args = args
_check_types(checkable_args , in_)
# 执行
res = func(*args)
# 检查结果
if not type(res) in (tuple, list):
checkable_res = (res , )
else :
checkable_res = res
_check_types(checkable_res , out)
return res
def _check_types(elements, types):
""" subfunc that checks the types """
if len(elements) != len(types) :
raise TypeError('args count is wrong')
typed = enumerate(zip(elements,types))
for index , couple in typed :
arg , right_type = couple
if isinstance(arg , right_type):
continue
raise TypeError('arg #%d should be %s' %(index , right_type))
return check_run_check
return _typeassert
@typeassert((int,int) , (int,))
def add(a , b) :
return a + b
print(add(2,3))
# print(add(2.0,3.0))
2.缓存
缓存装饰器和参数检查很相似。不过它关注内部状态而不影响输出的函数。每组参数可以链接到一个唯一的结果上。
因此,缓存装饰器可以将输出与计算它的所需的函数放在一起,并且直接在后续的调用中返回它。
import time
import hashlib
import pickle
cache = {}
def is_obsolete(entry , duration):
return time.time() - entry['time'] > duration
def compute_key(func , *args , **kw) :
key = pickle.dumps((func.__name__ , args , kw)) # 函数名,参数打成一个元组,作为bytes返回
return hashlib.sha1(key).hexdigest() # 对bytes进行hash
def memorize(duration = 10):
def _memorize(func):
def find(*args , **kargs):
key = compute_key(func , args , kargs) # 计算hash
if key in cache and not is_obsolete(cache[key] , duration) :
print('got it!')
return cache[key]['value']
result = func(*args , **kargs)
cache[key] = {'value' : result , 'time':time.time()}
return result
return find
return _memorize
@memorize()
def very_very_very_complex_stuff(a,b) :
return a+b
print(very_very_very_complex_stuff(2,2) )
print(very_very_very_complex_stuff(2,2) )
print(cache)
print(very_very_very_complex_stuff(2,4) )
print(very_very_very_complex_stuff(2,4) )
print(cache)
3. 代理
class User:
def __init__(self,roles):
self.roles = roles
class Unauthorized(Exception):
pass
def protect(role):
def _protect(func):
def check(*args , **kargs):
return func(*args , **kargs)
return check
return _protect
class Secrets :
@protect('Mr.Krabs')
def Krabby_Burger_recipe(self):
print('the secret is nothing')
crab = User(('Mr.Krabs' , 'Boss'))
plankton = User(('Plankton' , 'thief'))
what = Secrets()
user = crab
what.Krabby_Burger_recipe()
user = plankton
what.Krabby_Burger_recipe
4.上下文提供者
from threading import RLock
lock = RLock()
def synchronized(func) :
def _synchronized(*args , **kargs):
lock.acquire()
try:
return func(*args , **kargs)
finally:
lock.release()
return _synchronized
@synchronized
def thread_safe():
pass