语境:
我希望能够装饰函数,以便我可以跟踪它们的统计信息。使用这篇文章作为参考,我开始尝试制作我自己的可调用装饰器对象。
这是我最终得到的结果:
def Stats(fn):
Class StatsObject(object):
def __init__(self, fn):
self.fn = fn
self.stats = {}
def __call__(self, obj, *args, **kwargs):
self.stats['times_called'] = self.stats.get('times_called', 0) + 1
return self.fn(obj, *args, **kwargs)
function = StatsObject(fn)
def wrapper(self, *args **kwargs):
return function(self, *args, **kwargs)
return wrapper
Class MockClass(object):
@Stats
def mock_fn(self, *args, **kwargs):
# do things
问题:
这实际上正确调用了 mock_fn 函数,但我没有对包装函数之外的 stats 对象的引用。即我不能这样做:
mc = MockClass()
mc.mock_fn()
mc.mock_fn.stats
# HasNoAttribute Exception
然后我尝试更改以下代码,认识到这是一个范围问题:
从:
function = StatsObject(fn)
def wrapper(self, *args **kwargs):
return function(self, *args, **kwargs)
return wrapper
至:
function = StatsObject(fn)
return function
但是我当然丢失了自引用(self 成为 StatsObject 实例,obj 成为第一个 arg,MockClass 对象自引用丢失)。
所以我明白为什么会发生第一个问题,但不是第二个。有什么方法可以将 MockClass 的自引用传递给 StatsObject__call__
函数?