python - 获取装饰器的可变关键字参数的值
问题描述
我有以下代码,其中我只是有一个用于缓存函数结果的装饰器,作为具体实现,我使用了 Fibonacci 函数。
在玩弄了代码之后,我想打印在包装器cache
中启动的变量。cache
(这不是因为我怀疑缓存可能有问题,我只是想知道如何在不进入调试模式的情况下访问它并在装饰器中放置断点)
我试图fib_w_cache
在调试模式下探索该功能,这实际上应该是 Wrapped fib_w_cache
,但没有成功。
import timeit
def cache(f, cache = dict()):
def args_to_str(*args, **kwargs):
return str(args) + str(kwargs)
def wrapper(*args, **kwargs):
args_str = args_to_str(*args, **kwargs)
if args_str in cache:
#print("cache used for: %s" % args_str)
return cache[args_str]
else:
val = f(*args, **kwargs)
cache[args_str] = val
return val
return wrapper
@cache
def fib_w_cache(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib_w_cache(n-2) + fib_w_cache(n-1)
def fib_wo_cache(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib_wo_cache(n-1) + fib_wo_cache(n-2)
print(timeit.timeit('[fib_wo_cache(i) for i in range(0,30)]', globals=globals(), number=1))
print(timeit.timeit('[fib_w_cache(i) for i in range(0,30)]', globals=globals(), number=1))
解决方案
我承认这在某种意义上不是一个“优雅”的解决方案,但请记住,python 函数也是对象。因此,对您的代码稍作修改后,我设法将缓存作为修饰函数的属性注入:
import timeit
def cache(f):
def args_to_str(*args, **kwargs):
return str(args) + str(kwargs)
def wrapper(*args, **kwargs):
args_str = args_to_str(*args, **kwargs)
if args_str in wrapper._cache:
#print("cache used for: %s" % args_str)
return wrapper._cache[args_str]
else:
val = f(*args, **kwargs)
wrapper._cache[args_str] = val
return val
wrapper._cache = {}
return wrapper
@cache
def fib_w_cache(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib_w_cache(n-2) + fib_w_cache(n-1)
@cache
def fib_w_cache_1(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib_w_cache(n-2) + fib_w_cache(n-1)
def fib_wo_cache(n):
if n == 0: return 0
elif n == 1: return 1
else:
return fib_wo_cache(n-1) + fib_wo_cache(n-2)
print(timeit.timeit('[fib_wo_cache(i) for i in range(0,30)]', globals=globals(), number=1))
print(timeit.timeit('[fib_w_cache(i) for i in range(0,30)]', globals=globals(), number=1))
print(fib_w_cache._cache)
print(fib_w_cache_1._cache) # to prove that caches are different instances for different functions
推荐阅读
- database - 后端:远程与本地 sql 数据库
- excel - 如何使用 Wkst 2 上的数据透视表按 wkst 1 中的单元格值过滤数据透视表。如何修改我的代码?
- c - 如何在嵌入式上比较字符串日期 GMT
- c# - 即使在将属性数据属性设置为“NotMapped”之后,也会出现“无效的列名 ...”
- javascript - 如何将文件名数组转换为 JSON 并添加密钥
- sql - 汇总未按预期聚合
- cassandra - Cassandra 或其他 nosql 数据库中的少对多建模
- r - geom_text 的位置参数设置不同的标签
- php - 生成 JSON API 响应后,数字数组索引丢失
- metal - 线程组中的线程如何协同工作?