Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.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 decorator?_Python_Caching_Decorator_Python Decorators - Fatal编程技术网

如何编写用于缓存的python decorator?

如何编写用于缓存的python decorator?,python,caching,decorator,python-decorators,Python,Caching,Decorator,Python Decorators,我正在尝试为memoize编写python装饰程序。 我有几个问题 @memoize如何转换为memoize类的调用函数 为什么init需要一个参数 缓存存储在哪里?它是与每个函数关联的还是全局变量?i、 e如果我使用@memoize for,会有两个缓存对象吗 多功能 我得到编译错误 Traceback (most recent call last): File "memoize.py", line 17, in <module> @memoize TypeError

我正在尝试为memoize编写python装饰程序。 我有几个问题

  • @memoize如何转换为memoize类的调用函数
  • 为什么init需要一个参数
  • 缓存存储在哪里?它是与每个函数关联的还是全局变量?i、 e如果我使用@memoize for,会有两个缓存对象吗 多功能
  • 我得到编译错误

    Traceback (most recent call last):
      File "memoize.py", line 17, in <module>
        @memoize
    TypeError: __init__() takes exactly 1 argument (2 given)
    
    回溯(最近一次呼叫最后一次):
    文件“memoize.py”,第17行,在
    @回忆
    TypeError:\uuuu init\uuuuuu()正好接受1个参数(给定2个)
    
  • 您应该记住,
    @decorator
    只是
    func=decorator(func)
    的一种语法糖。所以这里有一个区别:
  • (一)

    func = decorator(func)  # Just call of __init__
    func(...)               # Call of decorator.__call__
    
    但是(2)

    类似于

    # Call of __init__ plus call of __call__
    func = decorator(some_param)(func)  
    # Call of closure returned by decorator.__call__
    func(...)   
    
  • 您已经实现了decorator接受(2)语法的参数,但在使用它们时,并没有提供它们,如示例(1)所示。这就是为什么
    \uuuu init\uuuu
    抱怨,它接收
    func
    作为第二个参数

  • 您应该在
    wrapper
    闭包中编写
    self.cache
    ,这样
    wrapper
    将引用相应的
    decorator
    对象。只写
    缓存
    会导致全局变量搜索失败

  • UPD:我将您的代码更改为接近(1):


    你真的想从头开始写这个吗?是的。我正在学习python DecorsorsOK,只是仔细检查一下,因为有一个
    lru缓存
    decorator。如果你看到这个例子,缓存是memoize类的一个成员变量。没有包装我已经把你的方法改为(1)并发布了代码,但是我建议你应该仔细阅读我的解释。好的。现在应该如何添加ttl?我想使用@memoize(ttl=10)。我尝试在类中的init函数中添加一个参数,但再次出现错误。他说,我希望你会问这个问题。然后您需要将代码从方法(1)更改为(2)。使用原始代码(但更改
    缓存
    ->
    self.cache
    )。请看我对第二个问题的回答。这是一个非常有用的Python修饰符,适用于许多应用程序。谢谢分享!
    func = decorator(func)  # Just call of __init__
    func(...)               # Call of decorator.__call__
    
    @decorator(some_param)
    def func():
         ...
    
    # Call of __init__ plus call of __call__
    func = decorator(some_param)(func)  
    # Call of closure returned by decorator.__call__
    func(...)   
    
    class memoize:
        def __init__(self, function):
            self.cache = {}
            self.function = function
    
        def __call__(self, *args, **kwargs):        
            key = str(args) + str(kwargs)
            if key in self.cache:
                return self.cache[key]
    
            value = self.function(*args, **kwargs)
            self.cache[key] = value
            return value
    
    @memoize
    def fib(n):
        if n in (0, 1):
            return 1
        else:
            return fib(n-1) + fib(n-2)
    
    for i in range(0, 10):
        print(fib(i))
    
    print(fib.cache)