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

如何动态设置Python函数load_or_set_cache的返回类型?

问题描述

我有一组包含key/ID和函数的字典,这些字典用作标识符,指向特定缓存键和更新该缓存键关联数据的函数。

from typing import TypedDict, List

class CacheIdentifier(TypedDict):
    key: str
    func: Callable

def function_to_fetch_cache_data() -> List[str]:
    return ["a", "b", "c"]

IDENTIFIER: CacheIdentifier = {
    "key": "my_cache_key",
    "func": function_to_fetch_cache_data
}

我还有一个名为load_or_set_cache的函数,它接收一个标识符对象,功能是检查缓存键是否关联有数据:如果不存在,则使用传入的CacheIdentifier对象的func参数获取新数据并存入缓存;如果存在,则直接获取缓存数据。

def load_or_set_cache(identifier: CacheIdentifier) -> Any:
    # 检查缓存数据是否存在的逻辑
    cached = cache.get(identifier["key"]) is not None  # 补充示例判断逻辑
    
    if not cached:
        cache_data = identifier["func"]()
        cache_key = identifier["key"]

        cache.set(cache_key, cache_data, TTL=3600)

    else:
        cache_key = identifier["key"]
        cache_data = cache.get(cache_key)     

    return cache_data

cache_data = load_or_set_cache(IDENTIFIER)

该函数返回获取到的缓存数据,数据类型取决于每个标识符中函数的返回类型。例如,若function_to_fetch_cache_data返回类型为List[str],则load_or_set_cache也应返回List[str],使cache_data的类型为List[str]。目前该函数的返回类型设为Any,请问是否可以根据传入的缓存标识符中func的返回类型动态设置load_or_set_cache的返回类型?我尝试过TypeVars,但感觉它并不适合我的需求。


解决方案

完全可以实现,你需要结合泛型TypeVar和泛型TypedDict来让类型系统自动推导返回类型。之前觉得TypeVar不合适,大概率是没搭配泛型TypedDict使用,具体修改如下:

步骤说明

  1. 定义一个泛型TypeVar,用来标记函数的返回类型
  2. 将CacheIdentifier改为泛型TypedDict,让它的func字段类型与这个TypeVar绑定
  3. 给load_or_set_cache添加泛型参数,让函数返回类型与CacheIdentifier中func的返回类型保持一致

修改后完整代码

from typing import TypedDict, List, Callable, TypeVar, Optional

# 定义泛型TypeVar,表示函数的返回类型
T = TypeVar('T')

# 泛型版本的CacheIdentifier,绑定func的返回类型为T
class CacheIdentifier(TypedDict, generic=T):
    key: str
    func: Callable[[], T]

def function_to_fetch_cache_data() -> List[str]:
    return ["a", "b", "c"]

# 此时IDENTIFIER的类型会被自动推导为CacheIdentifier[List[str]],无需手动标注
IDENTIFIER = {
    "key": "my_cache_key",
    "func": function_to_fetch_cache_data
}

# 泛型函数,返回类型与传入的CacheIdentifier中func的返回类型一致
def load_or_set_cache(identifier: CacheIdentifier[T]) -> T:
    # 检查缓存是否存在的示例逻辑
    cached_data: Optional[T] = cache.get(identifier["key"])
    
    if cached_data is None:
        cached_data = identifier["func"]()
        cache.set(identifier["key"], cached_data, TTL=3600)
    
    # 断言缓存数据非空,确保类型安全(也可以根据实际业务处理None场景)
    assert cached_data is not None
    return cached_data

# 此时cache_data的类型会被自动推导为List[str],而非Any
cache_data = load_or_set_cache(IDENTIFIER)

关键细节

  • 泛型CacheIdentifier[T]会让每个标识符的func返回类型被明确绑定,类型检查器能准确跟踪类型信息
  • load_or_set_cache通过泛型参数T,直接复用CacheIdentifier中func的返回类型作为自身返回类型,实现了动态匹配
  • 如果缓存的get方法可能返回None,可以选择返回T | None,或者通过断言、默认值等方式处理,避免类型错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:31:04