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

如何避免仅需执行一次的耗时类方法被重复调用?

Pythonic 实现耗时方法仅执行一次的方案

下面提供几种符合Python风格的解决方案,既保证耗时计算只执行一次,又能正确处理类型提示:

方法1:使用 functools.cache(Python 3.9+)或 lru_cache

利用标准库的缓存装饰器,自动帮你缓存方法返回值,每个实例只会触发一次耗时计算:

from typing import List
from functools import cache


class Example:
    def __init__(self) -> None:
        pass

    @cache
    def my_value(self) -> int:
        """耗时计算,仅执行一次"""
        print("执行耗时计算...")  # 用于验证只执行一次
        return 1  # 替换为实际耗时逻辑

    def do_something_with_my_value(self) -> List[int]:
        """重复使用my_value的结果"""
        return [x + self.my_value() for x in range(1, 1000)]


# 测试:第二次调用do_something_with_my_value不会再触发计算
e = Example()
print(e.do_something_with_my_value())
print(e.do_something_with_my_value())

说明:装饰器会自动处理缓存逻辑,类型提示完全正常,不需要修改返回值类型标注。如果使用Python 3.8及以下版本,改用@lru_cache(maxsize=None)即可。

方法2:手动实现懒加载(实例属性缓存)

自己维护一个私有实例属性存储计算结果,第一次调用时执行计算,后续直接返回缓存值:

from typing import List, Optional


class Example:
    def __init__(self) -> None:
        self._my_value: Optional[int] = None  # 初始为None,标记未计算

    def my_value(self) -> int:
        """耗时计算,仅执行一次"""
        if self._my_value is None:
            print("执行耗时计算...")
            self._my_value = 1  # 替换为实际耗时逻辑
        return self._my_value

    def do_something_with_my_value(self) -> List[int]:
        """重复使用my_value的结果"""
        return [x + self.my_value() for x in range(1, 1000)]

说明:通过_my_value私有属性控制计算逻辑,类型提示用Optional[int]标记初始状态,方法返回值仍标注为int,完全符合类型检查要求。

方法3:使用 @property 实现懒加载

将方法转为属性,第一次访问时执行计算,后续直接返回缓存值,代码更简洁:

from typing import List, Optional


class Example:
    def __init__(self) -> None:
        self._my_value: Optional[int] = None

    @property
    def my_value(self) -> int:
        """耗时计算,仅执行一次"""
        if self._my_value is None:
            print("执行耗时计算...")
            self._my_value = 1  # 替换为实际耗时逻辑
        return self._my_value

    def do_something_with_my_value(self) -> List[int]:
        """重复使用my_value的结果"""
        return [x + self.my_value for x in range(1, 1000)]  # 调用时无需加括号

说明:用@property装饰后,访问self.my_value就像访问普通属性一样,逻辑更直观,类型提示也完全正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:05:59