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

为何自定义字典赋值给函数__dict__后,f.k2无法解析而f.k1可以?

为什么f.k1能访问但f.k2不行?

这个问题的核心在于Python函数对象的属性查找机制和你自定义字典子类的行为不匹配,我来给你拆解清楚:

先看你的代码逻辑

你自定义了MyDict子类,只重写了__getitem__方法——当键是'k2'时返回'v2',其他情况沿用父类dict的逻辑。然后你把函数f的__dict__替换成了这个MyDict的实例(初始化时传入了{'k1': 'v1'})。

为什么f.k1正常?

当你访问f.k1时:

  1. Python首先检查'k1'是不是f.__dict__里的键(因为'k1'确实在初始化的字典里,'k1' in f.__dict__返回True)
  2. 确认键存在后,Python会调用f.__dict__['k1']来获取值,这时候触发你重写的__getitem__,顺利返回'v1'

为什么f.k2报错?

而访问f.k2时,问题出在属性查找的第一步:

  1. Python会先检查'k2'是否存在于f.__dict__的键集合中。但你没有重写MyDict的__contains__方法,这个方法继承自父类dict,而'k2'并不是这个字典的实际键,所以'k2' in f.__dict__返回False
  2. 函数对象的属性查找逻辑是:只有当属性名存在于__dict__的键里时,才会去调用__getitem__取值;如果键不存在,直接抛出AttributeError,根本不会走到你重写的__getitem__那一步

怎么解决?

如果想让f.k2能正常访问,你需要同时重写MyDict的__contains__方法,让它在检查'k2'时返回True:

class MyDict(dict):
    def __getitem__(self, item):
        if item == 'k2':
            return 'v2'
        return super().__getitem__(item)
    
    def __contains__(self, item):
        if item == 'k2':
            return True
        return super().__contains__(item)

修改后再测试,f.k2就能返回'v2'了。

另外补充个小细节:直接调用f.__dict__['k2']是能拿到'v2'的,因为这会直接触发__getitem__;但.属性访问是走完整的属性查找流程,两者的逻辑不一样哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:35:44