对函数局部进行控制,这个局部最常见的就是对参数的控制
from functools import partial
def run(name, age):
print(name, age)
run2 = partial(run, age=18)
run2("laowang")
输出:
laowang, 18
主要用途是装饰器函数,它包装装饰函数并返回包装函数的函数定义而不是原始函数定义
from functools import update_wrapper
def wrap_run(func):
def run(*args, **kwargs):
print('run')
return func(*args, **kwargs)
return update_wrapper(run, func)
@wrap_run
def run2():
print('run2')
print(run2.__name__)
输出:run2
如果不使用 update_wrapper
def wrap_run(func):
def run(*args, **kwargs):
print('run')
return func(*args, **kwargs)
return run
@wrap_run
def run2():
print('run2')
print(run2.__name__)
输出:run
调用函数装饰器 partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) 的简写
from functools import wraps
def wrap_run(func):
@wraps(func)
def run(*args, **kwargs):
print('run')
return func(*args, **kwargs)
return run
@wrap_run
def run2():
print('run2')
print(run2.__name__)
输出:run2
from functools import partialmethod
class Cell(object):
def __init__(self):
self._alive = False
@property
def alive(self):
return self._alive
def set_state(self, state):
self._alive = state
set_alive = partialmethod(set_state, True)
set_dead = partialmethod(set_state, False)
c = Cell()
print(c.alive)
c.set_alive()
print(c.alive)
c.set_dead()
print(c.alive)
输出:
False
True
False
定义泛型函数,调度发生在第一个参数的类型上,
对于使用类型注释的函数,装饰器将自动推断第一个参数的类型
from functools import singledispatch
@singledispatch
def func(*args, **kwargs):
pass
@func.register(float)
@func.register(int)
def _(arg, verbose=False):
if verbose:
print("numbers, eh?", end=" ")
print(arg)
@func.register(str)
def _(arg, verbose=False):
if verbose:
print("str, eh?", end=" ")
print(arg)
func(121, verbose=True)
func(121.1212, verbose=True)
func('aaaaa', verbose=True)
print(func.registry.keys())
输出:
numbers, eh? 121
numbers, eh? 121.1212
str, eh? aaaaa
dict_keys([, , , ])
lru 即:least recently used
如果将maxsize设置为None,则禁用LRU功能,并且缓存可以无限制地增长。当maxsize是2的幂时,LRU功能表现最佳。
如果typed设置为true,则将分别缓存不同类型的函数参数。例如,f(3)并且f(3.0)将被视为产生截然不同的结果不同的呼叫。
为了帮助测量缓存的有效性并调整maxsize 参数,包装函数使用一个cache_info() 函数进行检测,该函数返回一个命名元组,显示hits,misses, maxsize和currsize。
装饰器还提供cache_clear()清除或使缓存无效的功能。
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print([fib(n) for n in range(16)])
print(fib.cache_info())
输出:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)