Python模块加载JSON的最佳实践:按需加载与缓存实现
解决Python模块中JSON数据的懒加载与缓存问题
针对你遇到的每次调用fetch_data都重复加载大JSON文件的问题,这里提供几种符合「懒加载+单次缓存」需求的实现方案:
方案一:利用函数属性实现极简缓存
直接在函数内部维护一个缓存属性,只有首次调用时才加载文件:
import json import os def fetch_data(k): # 检查是否已缓存数据,首次调用时加载 if not hasattr(fetch_data, "_cached_data"): fname = os.path.join( os.path.abspath(os.path.dirname(__file__)), "data.json" ) with open(fname, "r") as f: fetch_data._cached_data = json.load(f) return fetch_data._cached_data[k]
这个方案无需额外依赖,代码最简洁,完全满足「仅在需要时加载、加载后复用」的要求。
方案二:用标准库装饰器分离加载逻辑
如果想把数据加载和键值获取的逻辑分开,可以用functools.lru_cache缓存加载结果:
import json import os from functools import lru_cache def _load_data(): # 单独封装数据加载逻辑 fname = os.path.join( os.path.abspath(os.path.dirname(__file__)), "data.json" ) with open(fname, "r") as f: return json.load(f) # 缓存_load_data的结果,无参数情况下只会执行一次 @lru_cache(maxsize=None) def _get_cached_data(): return _load_data() def fetch_data(k): return _get_cached_data()[k]
这种方式逻辑更清晰,后续如果需要修改加载逻辑,只需调整_load_data函数即可。
方案三:类实现(扩展性更强)
如果后续可能需要添加数据刷新、多数据源切换等功能,用类来封装会更灵活:
import json import os class DataFetcher: def __init__(self): self._cached_data = None # 初始化时不加载数据 def _load_data(self): fname = os.path.join( os.path.abspath(os.path.dirname(__file__)), "data.json" ) with open(fname, "r") as f: return json.load(f) def fetch(self, k): # 首次调用fetch时才加载数据 if self._cached_data is None: self._cached_data = self._load_data() return self._cached_data[k] # 创建全局实例,供外部直接调用 data_fetcher = DataFetcher()
使用时直接调用实例的fetch方法:
from mymodule import data_fetcher for k in "ABCD": print(data_fetcher.fetch(k))
这三种方案都不会在模块导入时就加载JSON文件,只有当第一次调用数据获取函数/方法时才会读取文件,之后所有调用都直接复用内存中的缓存数据,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者Bulkilol
相关产品推荐
相关产品推荐

