Python 2.6 decorator with parameter
Question: I'm writing filesystem cache decorator for django. The problem is when I
decorate my function with this decorator and @register.simple_tag I get
my_decorated_func takes 0 arguments error (when page is loaded with this
template tag)

    
    
    from functools import wraps
    
    from django.conf import settings
    from django.core.cache import get_cache
    from django.utils.http import urlquote
    from django.utils.hashcompat import md5_constructor
    
    FILESYSTEM_CACHE_NAME = 'filesystem'
    
    
    def filesystem_cache(key_prefix, cache_time=None):
        """
        Caches function based on key_prefix and function args/kwargs.
        Stores function result in filesystem cache for a certain cache_time.
        """
        if cache_time:
            FILESYSTEM_CACHE_TIME = cache_time
        else:
            FILESYSTEM_CACHE_TIME = settings.CACHES['filesystem'].get('TIMEOUT')
        def wrapfunc(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                full_args = list()
                full_args.extend(args)
                for k, v in kwargs.items():
                    full_args.append('%s:%s' % (str(k), str(v)))
                md5_args = md5_constructor(u':'.join([urlquote(var) for var in full_args]))
                cache_key = 'template.cache.%s.%s' % (key_prefix, md5_args.hexdigest())
                filesystem_cache = get_cache(FILESYSTEM_CACHE_NAME)
                cached_value = filesystem_cache.get(cache_key)
                if cached_value:
                    # if cached value exists - return it
                    return cached_value
                result = func(*args, **kwargs)
                filesystem_cache.set(cache_key, result, FILESYSTEM_CACHE_TIME)
                return result
            return wrapper
        return wrapfunc
    
    @register.simple_tag
    @filesystem_cache('countrypages')
    def my_decorated_func(country, date, locale=None):
    

Calling my_decorated_func with parameters from console is ok, but rendering a
template :

    
    
    {% my_decorated_func country todays_date 'en' %}
    

gives me an error.

Any suggestions ? Thanks !


Answer: Here is a solution : pip install decorator, than

    
    
    def filesystem_cache(key_prefix, cache_time=None):
        """
        Caches function based on key_prefix and function args/kwargs.
        Stores function result in filesystem cache for a certain cache_time.
        """
        if cache_time:
            FILESYSTEM_CACHE_TIME = cache_time
        else:
            FILESYSTEM_CACHE_TIME = settings.CACHES['filesystem'].get('TIMEOUT')
        @decorator
        def wrapfunc(func, *args, **kwargs):
            full_args = list()
            full_args.extend(args)
            for k, v in kwargs.items():
                full_args.append('%s:%s' % (str(k), str(v)))
            md5_args = md5_constructor(u':'.join([urlquote(var) for var in full_args]))
            cache_key = 'template.cache.%s.%s' % (key_prefix, md5_args.hexdigest())
            filesystem_cache = get_cache(FILESYSTEM_CACHE_NAME)
            cached_value = filesystem_cache.get(cache_key)
            if cached_value:
                # if cached value exists - return it
                return cached_value
            result = func(*args, **kwargs)
            filesystem_cache.set(cache_key, result, FILESYSTEM_CACHE_TIME)
            return result
        return wrapfunc
    

