You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Python装饰器实现多类下载方法的通用文件缓存逻辑

你当前设计的装饰器需要在绑定到方法时就传入filepath和use_cache参数,但filepath是类实例化后才会生成的实例属性,use_cache是调用download方法时才传入的动态参数,二者都无法在定义方法阶段提前传入装饰器,所以这个思路不可行。

以下是两种可行的通用解决方案:

方案1:适配实例方法的装饰器

利用实例方法第一个参数是self的特性,在装饰器内部直接获取实例的filepath属性,以及调用时传入的use_cache参数,不需要提前传参:

from functools import wraps
from pathlib import Path

def download_cache(func):
    @wraps(func)
    def wrapper(self, use_cache=True, *args, **kwargs):
        # 通用缓存逻辑
        if use_cache and self.filepath.exists():
            return self.filepath
        # 执行子类自定义的下载逻辑
        func(self, use_cache=use_cache, *args, **kwargs)
        return self.filepath
    return wrapper

使用方式非常简单,只需要给每个类的download方法加上装饰器,方法内部只保留差异化的下载代码即可:

class Data(object):
    def __init__(self):
        self.filepath = Path("filepath")  

    @download_cache
    def download(self, use_cache=True):
        # 仅保留差异化的下载实现
        print(f"downloading to {self.filepath}")

方案2:基类继承(更适合流水线多类场景)

如果你的所有数据类都是流水线内的同类型组件,用抽象基类统一收敛公共逻辑会更易维护,后续要调整缓存规则、增加重试/日志等公共能力只需要修改基类即可:

from pathlib import Path
from abc import ABC, abstractmethod

class BaseDownloadableData(ABC):
    # 约定所有子类必须定义filepath属性
    filepath: Path

    def download(self, use_cache=True):
        # 全局统一缓存逻辑
        if use_cache and self.filepath.exists():
            return self.filepath
        # 调用子类实现的专属下载逻辑
        self._download_logic()
        return self.filepath

    @abstractmethod
    def _download_logic(self):
        """子类实现具体的下载逻辑,不需要处理缓存判断"""
        pass

子类只需要继承基类,实现下载逻辑即可:

class CustomData(BaseDownloadableData):
    def __init__(self):
        self.filepath = Path("custom_filepath")  

    def _download_logic(self):
        # 仅写差异化的下载代码
        print(f"downloading custom data to {self.filepath}")

方案选择建议

  • 如果只是给零散的几个类加缓存能力,选择装饰器更灵活,不需要修改类的继承关系
  • 如果是同一条流水线内的多个数据类统一规范,选择基类继承可维护性更高

内容的提问来源于stack exchange,提问作者turnerm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:36:03