code: def method(cache_name, key_prefix=None):
      
      def decorator(func):
          if (func.__name__ in ['cause_repertoire', 'effect_repertoire'] and
                  not config.CACHE_REPERTOIRES):
              return func
  
          @wraps(func)
          def wrapper(obj, *args, **kwargs):
              cache = getattr(obj, cache_name)
  
              # Delegate key generation
              key = cache.key(*args, _prefix=key_prefix, **kwargs)
  
              # Get cached value, or compute
              value = cache.get(key)
              if value is None:  # miss
                  value = func(obj, *args, **kwargs)
                  cache.set(key, value)
              return value
  
          return wrapper
      return decorator
docs: Caching decorator for object-level method caches.
  
      Cache key generation is delegated to the cache.
  
      Args:
          cache_name (str): The name of the (already-instantiated) cache
              on the decorated object which should be used to store results
              of this method.
          *key_prefix: A constant to use as part of the cache key in addition
              to the method arguments.