目标是包装一个函数或方法,并使用包装函数独有的包装器来携带数据。
作为一个例子 - 假设我有方法myThing
的对象foo
。我想用myThing.foo
包裹myWrapper
,并且(作为示例)我希望能够计算myThing.foo
实际调用的次数。
到目前为止,我发现唯一有效的方法是只为对象添加一个属性 - 但这感觉有点笨拙。
class myThing(object):
def foo(self):
return "Foo called."
def myWrap(some_func):
def _inner(self):
#a wild kludge appears!
try:
self.count += 1
except AttributeError:
self.count = 0
return some_func(self)
return _inner
Stick = myThing()
myThing.foo = myWrap(myThing.foo)
for i in range(0, 10):
Stick.foo() ##outputs "Foo called." 10 times
Stick.count # the value of Stick.count
所以,这实现了目标,事实上如果有myThing
的多个实例,那么每个实例都会跟踪它自己的self.count值,这是我预期目标的一部分。但是,我不确定为myThing
的每个实例添加属性是实现此目的的最佳方法。例如,如果我要为不属于对象或类的函数编写包装器,则向不存在的对象添加属性将不会执行任何操作。
也许在我理解包装方法或函数时实际发生的事情上存在漏洞。我知道可以在闭包中维护某种静态数据,如下例所示:
def limit(max_value):
def compare(x):
return x > max_value
return compare
isOverLimit = limit(30)
isOverLimit(45) #returns True
isOverLimit(12) #returns False
alsoOver = limit(20)
alsoOver(25) # returns True
isOverLimit(25) # returns False
第二个示例证明它不仅仅是修改limit
的原始实例,并且isOverLimit
继续按照创建第二个alsoOver
之前的方式执行操作。所以我觉得包装器有一种方法可以随身携带增量变量,而我只是遗漏了一些明显的东西。
答案 0 :(得分:1)
似乎这是Counting python method calls within another method
的欺骗简短的回答是在要计算的方法/函数上使用装饰器,并让装饰器将计数器存储为函数属性。请参阅我链接的问题中的答案。