如何在外部模块类中使用Flask-Caching的@cache装饰器?
解决Flask-Caching在独立模块类方法中无法使用的问题
问题背景
基于Flask开发的NGINX认证模块需要调用LDAP服务器,为减少高开销的LDAP调用,计划用flask-caching缓存响应。但在独立的ldap.py模块中,Ldap类的方法无法使用@cache.memoized装饰器,报错name 'cache' is not defined。尝试循环导入会引发错误,将类移到main.py虽可行但会导致文件臃肿,希望通过合理方式解决缓存实例的访问问题。
可行解决方案
方案1:将Cache实例抽离到独立扩展模块(推荐)
把Flask扩展实例单独放在一个模块中,彻底避免循环导入,同时保持代码结构清晰,符合Flask扩展使用规范。
- 创建
extensions.py:
from flask_caching import Cache # 先初始化空的cache实例 cache = Cache()
- 修改
main.py:
from flask import Flask from extensions import cache from ldap import Ldap app = Flask(__name__) # 用init_app方法绑定Flask应用 cache.init_app(app) @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') @auth.login_required def index(path): code = 200 msg = "Another LDAP Auth" headers = [('x-username', getRegister('username')), ('x-groups', getRegister('matchedGroups'))] return msg, code, headers @auth.verify_password def login(username, password): ldap = Ldap() return ldap.validateUser(username, password)
- 修改
ldap.py:
from extensions import cache class Ldap: @cache.memoized(timeout=300) def validateUser(self, username, password): # LDAP查询逻辑 if <ldap query goes here>: return True return False
方案2:通过构造函数注入Cache并动态装饰方法
在Ldap类初始化时传入cache实例,动态装饰目标方法,避免模块级别的导入依赖。
- 修改
ldap.py:
class Ldap: def __init__(self, cache): self.cache = cache # 动态用cache装饰validateUser方法 self.validateUser = self.cache.memoized(timeout=300)(self.validateUser) def validateUser(self, username, password): # LDAP查询逻辑 if <ldap query goes here>: return True return False
- 修改
main.py中的login函数:
@auth.verify_password def login(username, password): # 传入cache实例初始化Ldap ldap = Ldap(cache) return ldap.validateUser(username, password)
方案3:手动处理缓存逻辑(无需装饰器)
绕过装饰器,直接在方法内部使用cache的get和set方法手动管理缓存,避免模块导入问题。
修改ldap.py:
class Ldap: def validateUser(self, username, password): # 延迟导入cache,避免模块加载时的循环导入 from main import cache # 生成唯一缓存键 cache_key = f"ldap_validation_{username}" # 先尝试从缓存获取结果 cached_result = cache.get(cache_key) if cached_result is not None: return cached_result # 执行LDAP查询 result = <ldap query goes here> # 将结果存入缓存,设置超时时间 cache.set(cache_key, result, timeout=300) return result
内容的提问来源于stack exchange,提问作者Mariano Billinghurst
相关产品推荐
相关产品推荐

