def cacheResult(fn):
        """
        Method decorator: calculate the value on first access, produce the cached value thereafter.

        If the function takes arguments, the cache is a dictionary using all arguments as the key.

        Args:
            fn (method): function to decorate

        Returns:
            method: wrapper function with caching
        """
        cache = {}

        @functools.wraps(fn)
        def wrapper(*args, **kwargs):
            # Imperfect key generation (args may be passed as kwargs, so multiple ways to represent one key).
            key = args + tuple(kwargs.items())
            # Order of operations here tries to minimise use of exceptions.
            try:
                # Don't call the function here, as it may throw a TypeError itself (or from incorrect arguments).
                if key in cache:
                    return cache[key]
            except TypeError:
                # Key is not hashable, so we can't cache with these args -- just return the result.
                return fn(*args, **kwargs)
            # Not yet cached, so generate the result and store it.
            cache[key] = fn(*args, **kwargs)
            return cache[key]

        # Make cache accessible externally.
        wrapper.cache = cache
        return wrapper
def cacheResult(fn):
        """
        Method decorator: calculate the value on first access, produce the cached value thereafter.

        If the function takes arguments, the cache is a dictionary using all arguments as the key.

        Args:
            fn (method): function to decorate

        Returns:
            method: wrapper function with caching
        """
        cache = {}

        @functools.wraps(fn)
        def wrapper(*args, **kwargs):
            # Imperfect key generation (args may be passed as kwargs, so multiple ways to represent one key).
            key = args + tuple(kwargs.items())
            # Order of operations here tries to minimise use of exceptions.
            try:
                # Don't call the function here, as it may throw a TypeError itself (or from incorrect arguments).
                if key in cache:
                    return cache[key]
            except TypeError:
                # Key is not hashable, so we can't cache with these args -- just return the result.
                return fn(*args, **kwargs)
            # Not yet cached, so generate the result and store it.
            cache[key] = fn(*args, **kwargs)
            return cache[key]

        # Make cache accessible externally.
        wrapper.cache = cache
        return wrapper
def cacheResult ( fn ) : cache = { } @ functools . wraps ( fn ) def wrapper ( * args , * * kwargs ) : # Imperfect key generation (args may be passed as kwargs, so multiple ways to represent one key). key = args + tuple ( kwargs . items ( ) ) # Order of operations here tries to minimise use of exceptions. try : # Don't call the function here, as it may throw a TypeError itself (or from incorrect arguments). if key in cache : return cache [ key ] except TypeError : # Key is not hashable, so we can't cache with these args -- just return the result. return fn ( * args , * * kwargs ) # Not yet cached, so generate the result and store it. cache [ key ] = fn ( * args , * * kwargs ) return cache [ key ] # Make cache accessible externally. wrapper . cache = cache return wrapper
Method decorator: calculate the value on first access, produce the cached value thereafter.

        If the function takes arguments, the cache is a dictionary using all arguments as the key.

        Args:
            fn (method): function to decorate

        Returns:
            method: wrapper function with caching
Method decorator : calculate the value on first access produce the cached value thereafter .