#!/usr/bin/env python

"""
Content-based cache.
"""

import chash
import cachetools
import functools

def _cachedmethod(cache, arg_idx):
    def decorator(method):
        def wrapper(self, *args, **kwargs):
            key = chash.chash(args[arg_idx])
            try:
                return cache[key]
            except KeyError:
                pass
            result = method(self, *args, **kwargs)
            cache[key] = result
            return result
        return functools.update_wrapper(wrapper, method)
    return decorator

def lfu_cache_method(maxsize=128, arg_idx=0):
    return _cachedmethod(cachetools.LFUCache(maxsize), arg_idx)





@@ -124,17 +124,791 @@
 he, 
-arg_idx):
+key_args, enabled=True):%0A    %22%22%22%0A    Class instance method memoization decorator.%0A%0A    Memoizes the returned value of a class instance method by hashing the%0A    specified arguments to the hash.%0A%0A    Parameters%0A    ----------%0A    cache : dict-like%0A        Cache.%0A    key_args : int, slice, or str%0A        Assuming that %60args%60 and %60kwargs%60 respectively are the sequential%0A        and named parameters passed to the wrapped function, %60key_args%60 indicates which%0A        of those parameters are hashed to obtain the key for%0A        a cached result. An int indicates an index into %60args%60, a slice%0A        indicates a tuple containing a range of elements in %60args%60, and a str%0A        indicates a single named parameter.%0A    enabled : bool%0A        If False, don't cache any results.%0A    %22%22%22%0A
 %0A   
@@ -921,16 +921,25 @@
 ecorator
+_disabled
 (method)
@@ -952,42 +952,192 @@
     
-def wrapper(self, *args, **kwargs)
+return method%0A%0A    def decorator_enabled(method):%0A        if type(key_args) in set(%5Bint, slice%5D):%0A            makekey = lambda *args, **kwargs: chash.chash(args%5Bkey_args%5D)%0A        else
 :%0A  
@@ -1146,21 +1146,49 @@
         
+make
 key =
+ lambda *args, **kwargs:
  chash.c
@@ -1196,21 +1196,147 @@
 ash(
+kw
 args%5B
-arg_idx%5D
+key_args%5D)%0A        def wrapper(self, *args, **kwargs):%0A            print '%3E', args, kwargs%0A            key = makekey(*args, **kwargs
 )%0A  
@@ -1538,24 +1538,166 @@
 eturn result
+%0A%0A        # Make the cache accessible as an attribute of the wrapped function for%0A        # diagnostic purposes:%0A        wrapper.cache = cache
 %0A        ret
@@ -1746,28 +1746,101 @@
 od)%0A
+%0A
     
-return decorator
+if enabled:%0A        return decorator_enabled%0A    else:%0A        return decorator_disabled
 %0A%0Ade
@@ -1875,17 +1875,32 @@
 28, 
-arg_idx=0
+key_args=0, enabled=True
 ):%0A 
@@ -1957,17 +1957,620 @@
 e), 
-arg_idx)%0A%0A%0A
+key_args)%0A%0Aif __name__ == '__main__':%0A    class Foo(object):%0A        @lfu_cache_method(10, 0)%0A        def meth(self, x, y, z):%0A            return x+y+z%0A%0A    f = Foo()%0A    print f.meth(1, 2, 3)%0A    print f.meth.cache%0A    print f.meth(4, 5, 6)%0A    print f.meth.cache%0A    # This should return the result cached for arguments (1, 2, 3):%0A    print f.meth(1, 7, 8)%0A    print f.meth.cache%0A%0A    class Bar(object):%0A        @lfu_cache_method(10, key_args='x')%0A        def meth(self, x=1, y=2, z=3):%0A            return x+y+z%0A%0A        def meth2(self, x, y, z):%0A            return x+y+z%0A%0A    b = Bar()%0A    print b.meth(1, 2, 3)
 %0A%0A

Add docstring to caching decorator, add argument to turn decorator on or off.