简体   繁体   中英

Most Pythonic way to abort a cache decorator?

Let's say I have a Flask app called server and I have the cached blueprint like the following, making use of the decorators in flask.ext.cache:

from flask import Blueprint, render_template, request, Response
from server import cache

some_blueprint = Blueprint('some_blueprint', __name__)

def make_cache_key(*args, **kwargs):
  return request.url

@some_blueprint.route('/')
@cache.cached(timeout = 3600, key_prefix = make_cache_key)
def foo():
  # do some stuff
  if some stuff succeeds:
    return something
  else:
    return "failed"

Now, suppose "do some stuff" is something which succeeds 99.9% of the time, in which case I want the decorator to cache the result, but fails 0.01% of the time, in which case I want the decorator to NOT cache the "failed" result.

What's the most Pythonic way to do this? Am I forced to abandon the beauty of decorators?

(rewriting my comments as an answer)

You can throw an exception in the foo() function, so that it will not be cached (most cache functions will pass an exception through, consult the documentation of yours) and catch it in a wrapper function to transform it to "failed" . This wrapper function may or may not be a decorator:

def exception_to_failed(func)
  def wrapper(*args, **kwds):
    try:
      res = func(*args, **kwds)
    except: # better catch only specific exceptions, of course
      return "failed"
    return res
  return wrapper

@some_blueprint.route('/')
@exception_to_failed
@cache.cached(timeout = 3600, key_prefix = make_cache_key)
def foo():
  # do some stuff
  if some stuff succeeds:
    return something
  else:
    raise Exception() # or just rely on "some stuff" raising it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM