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

如何以Pythonic方式正确重实现defaultdict?

正确实现Python defaultdict的方式

你之前的实现都漏了最关键的一步——把工厂函数生成的值插入字典,这正是collections.defaultdict的核心特性:用[]访问不存在的键时,不仅返回默认值,还会把这个值存进字典里。

正确的实现代码

from collections.abc import Callable

class DefaultDict(dict):
    def __init__(self, factory: Callable[[], any]):
        self.factory = factory
        super().__init__()

    def __missing__(self, key):
        value = self.factory()
        self[key] = value  # 核心:将生成的默认值存入字典
        return value

为什么这个实现能符合预期?

  • 当你用x['b']访问不存在的键时,Python会自动调用__missing__方法:生成默认值,把值绑定到该键存入字典,再返回值。这时候再调用x.get('b'),就能获取到已经存入的默认值,和官方defaultdict行为完全一致。
  • 不需要重写get、pop等方法:这些方法本身不会触发__missing__,它们的行为和普通dict保持一致——比如get在键不存在时返回None(或你指定的默认值),pop在无默认值时抛出KeyError,这完全符合官方defaultdict的设计。

验证测试用例

运行你给出的测试代码,现在所有断言都会返回True:

import collections

x = DefaultDict(lambda: 'no value :(')
y = collections.defaultdict(lambda: 'no value :(')
x['a'] = 'hello'
y['a'] = 'hello'
print(x['a'] == y['a'])  # True
print(x.get('a') == y.get('a'))  # True
print(x['b'] == y['b'])  # True
print(x.get('b') == y.get('b'))  # True

关于CPython实现的疑问

CPython的defaultdict确实只实现了__missing__逻辑,因为dict的内置[]访问逻辑会在键不存在时自动检查并调用该方法,其他方法(如get)本身不依赖__missing__,所以不需要额外重写——这也是最符合Python风格的实现方式:利用现有父类的行为,只补充差异逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:41:12