python装饰程序堆栈
我一直在努力更好地理解装饰器和闭包 我试图通过装饰功能来实现:python装饰程序堆栈,python,functional-programming,decorator,Python,Functional Programming,Decorator,我一直在努力更好地理解装饰器和闭包 我试图通过装饰功能来实现: 记住以前传递的值 计算函数被调用的次数 我想使用两个独立的装饰器来制作它——为了科学:) 因此,我成功地创建了这个工作代码(我承认,我使用了一些片段进行计数) 输出: some constant 1 [5] some constant 2 [5, 'something'] 现在我想把memoize函数改成一个整洁的pythonic装饰器。以下是我到目前为止得出的结论: class countcalls(object):
- 记住以前传递的值
- 计算函数被调用的次数
some constant
1
[5]
some constant
2
[5, 'something']
现在我想把memoize函数改成一个整洁的pythonic装饰器。以下是我到目前为止得出的结论:
class countcalls(object):
"Decorator that keeps track of the number of times a function is called."
__instances = {}
def __init__(self, f):
self.__f = f
self.__numcalls = 0
countcalls.__instances[f] = self
def __call__(self, *args, **kwargs):
self.__numcalls += 1
return self.__f(*args, **kwargs)
def count(self):
"Return the number of times the function f was called."
return countcalls.__instances[self.__f].__numcalls
@staticmethod
def counts():
"Return a dict of {function: # of calls} for all registered functions."
return dict([(f.__name__, countcalls.__instances[f].__numcalls) for f in countcalls.__instances])
class memoize(object):
past=[]
def __init__(self, f):
past = []
self.__f = f
def __call__(self, *args, **kwargs):
self.past.append(*args)
return self.__f(*args, **kwargs)
def showPast(self):
print self.past
@memoize
@countcalls
def dosth(url):
print dosth._memoize__f.count() ## <-- this is so UGLY
dosth.showPast()
def main():
dosth("one")
dosth("two")
if __name__ == '__main__':
main()
如何摆脱“丑陋”行(
print doss.\u memorize\u f.count()
)?换句话说,我如何直接调用堆叠装饰器的方法?(无需向decorators添加方法来调用其他decorator的方法-这不是我的观点)如果要访问特定的decorator结果,您仍然需要打开decorators,但此属性的“default”属性为\uuuuuuuuuuuuuuuuuuuu
。的Python 3版本为您设置此属性(通过,从Python 3.4开始),但您可以在自己的装饰器中手动执行相同的操作:
class memoize(object):
past=[]
def __init__(self, f):
past = []
self.__wrapped__ = self.__f = f
现在,您可以通过以下方式访问包装的callable:
dosth.__wrapper__.count()
wich是解包decorators的标准Pythonic方法。为什么要从函数内部访问decorators?我想在这种情况下,这是一种计算函数被调用多少次并根据它修改函数行为的好方法,这并不重要-如果我想在外部访问count属性如果你把计数器放在记忆器外面,我仍然需要使用dosth.\u memoize\u f.count()。
class memoize(object):
past=[]
def __init__(self, f):
past = []
self.__wrapped__ = self.__f = f
dosth.__wrapper__.count()