我正在尝试为缓存工具设置测试,其中缓存基于函数对象及其参数。要做这个测试,我需要访问我的属性中调用的确切函数,我无法弄清楚如何执行此操作。
缓存代码如下所示:
def cached(func):
"""
Decorator to cache function calls
"""
@wraps(func)
def wrapper(self, *args):
# The cache lives in the instance so that it gets garbage collected
if (func, args) not in self._cache:
self._cache[(func, args)] = func(self, *args)
return self._cache[(func, args)]
return wrapper
我有一个缓存的属性:
class SpatialMixin(object):
@property
@cached
def longitude_extrema(self):
return 25
该课程看起来像这样:
class MainClass(SomeOtherBaseClass,SpatialMixin):
pass
MyObject = MainClass()
我可以直接访问base_class.SpatialMixin.longitude_extrema.fget
,但这是一个与MyObject.longitude_extrema.fget
不同的对象(我用它来表示该属性的getter;你不能这样访问它,因为{{ 1}}只是数字25)。
那么,我如何访问MyObject.longitude_extrema
属性底层的函数?
答案 0 :(得分:1)
如果您尝试访问原始longitude_extrema
功能,则无法通过fget
找到该功能,因为原来的longitude_extrema
功能不是吸气。 wrapper
装饰器中创建的cached
函数是getter。
在Python 3.4+上,用functools.wraps
装饰的包装器有一个__wrapped__
属性,指向它包装的函数。您可以使用它来访问原始longitude_extrema
。 (此属性也存在于3.2和3.3中,但行为略有错误。)
在Python 2上,functools.wraps
没有设置__wrapped__
。虽然技术上可以通过直接闭包操作来获得包装函数,但它很笨拙,依赖于变量名,并且不是一个好的选择,特别是因为你控制了装饰器。您可以在__wrapped__
装饰器中自己设置cached
。