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

如何将缓存实例的元类用作其子类的__metaclass__?

使用缓存元类的方法

首先先把你给出的元类代码补全(看起来最后一行有点截断),完整的可运行版本大概是这样:

class _CachingMeta(type):
    __cache__ = {}
    def __init__(self, n, b, d):
        # 这里可以添加你的自定义初始化逻辑
        super(_CachingMeta, self).__init__(n, b, d)
    
    def __call__(cls, *a, **kw):
        # 生成缓存键,注意参数必须是可哈希的
        key = frozenset((cls, frozenset(a), frozenset(kw.items())))
        if key not in _CachingMeta.__cache__:
            _CachingMeta.__cache__[key] = super(_CachingMeta, cls).__call__(*a, **kw)
        return _CachingMeta.__cache__[key]

接下来分Python版本说明如何将这个元类应用到子类上:

Python 3 写法

在Python 3中,指定元类最直接的方式是在类定义时使用metaclass关键字参数:

class MyCachedClass(metaclass=_CachingMeta):
    def __init__(self, value):
        self.value = value

# 测试缓存效果
obj1 = MyCachedClass(10)
obj2 = MyCachedClass(10)
print(obj1 is obj2)  # 输出 True,说明是同一个实例

Python 2 写法

在Python 2中,需要在类内部定义__metaclass__属性:

class MyCachedClass:
    __metaclass__ = _CachingMeta
    def __init__(self, value):
        self.value = value

# 测试缓存效果
obj1 = MyCachedClass(10)
obj2 = MyCachedClass(10)
print(obj1 is obj2)  # 输出 True

补充说明

  • 你的元类通过重写__call__方法拦截了类的实例化过程,只有当对应的缓存键不存在时才会创建新实例,否则直接返回缓存中的实例。
  • 注意缓存键使用了frozenset,这要求你的位置参数*a和关键字参数**kw中的所有元素都必须是可哈希类型(比如不能是列表、字典这类可变且不可哈希的对象),否则会抛出TypeError。

内容的提问来源于stack exchange,提问作者dr-igor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:34:35