Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python装饰程序堆栈_Python_Functional Programming_Decorator - Fatal编程技术网

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()