Python中字典的Key和实例的属性的区别与联系

🧩 一、核心结论

字典的 key 不是字典实例的实例变量。 它们存放在字典对象的内部哈希表结构里,而不是像普通对象那样放在 __dict__ 属性中。


🧠 二、对象属性 vs 字典键的区别

对比项普通对象属性(attribute)字典键(key)
存储位置对象的 __dict__字典的内部哈希表
存取方式obj.attrgetattr(obj, "attr")d[key]d.get(key)
不存在时的错误AttributeErrorKeyError
是否出现在 dir()✅(会出现)❌(不会出现)
示例p.name → 从 p.__dict__ 查找d['name'] → 从哈希表查找


🧱 三、举例说明

class Person:
    def __init__(self):
        self.name = "Alice"

p = Person()
d = {"name": "Alice"}

# 普通对象
print(p.__dict__)   # {'name': 'Alice'}
print(getattr(p, "name"))  # ✅ "Alice"

# 字典对象
print(d.__dict__)   # ❌ AttributeError: dict 没有 __dict__
print(getattr(d, "name"))  # ❌ AttributeError: 'dict' 没有属性 name
print(d["name"])    # ✅ "Alice"


⚙️ 四、为什么 getattr(self.__data, name) 会报错

FrozenJson 中:

def __getattr__(self, name):
    try:
        return getattr(self.__data, name)
    except AttributeError:
        return FrozenJson.build(self.__data[name])

原因是:

  • self.__data 是一个字典;
  • getattr(self.__data, name) 查找的是字典对象的属性(比如 .keys、.items);
  • 而不是字典的键;
  • 所以当 name 不是字典方法时(比如 "name"),就会抛出 AttributeError;
  • 然后转而用 self.__data[name] 去取真正的键值。


🧩 五、类比总结

类比键/属性作用查找方式异常类型
字典存数据d["key"]KeyError
对象存属性getattr(obj, "attr") / obj.attrAttributeError


✅ 最终记忆口诀

🔹 “字典的键在哈希表,对象的属性在 __dict__。” 🔹 getattr() 查属性,不查 key。 🔹 键不存在抛 KeyError,属性不存在抛 AttributeError。


要不要我帮你画一个「对象 vs 字典」的内存结构图?

一张图能非常直观看出 __dict__ 和哈希表的区别。

文章标签:

评论(0)