Python中字典的Key和实例的属性的区别与联系
已于 2025年10月12日 16:52 修改
访问次数:0
🧩 一、核心结论
字典的 key 不是字典实例的实例变量。 它们存放在字典对象的内部哈希表结构里,而不是像普通对象那样放在 __dict__ 属性中。
🧠 二、对象属性 vs 字典键的区别
| 对比项 | 普通对象属性(attribute) | 字典键(key) |
|---|---|---|
| 存储位置 | 对象的 __dict__ | 字典的内部哈希表 |
| 存取方式 | obj.attr 或 getattr(obj, "attr") | d[key] 或 d.get(key) |
| 不存在时的错误 | AttributeError | KeyError |
是否出现在 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.attr | AttributeError |
✅ 最终记忆口诀
🔹 “字典的键在哈希表,对象的属性在 __dict__。” 🔹 getattr() 查属性,不查 key。 🔹 键不存在抛 KeyError,属性不存在抛 AttributeError。
要不要我帮你画一个「对象 vs 字典」的内存结构图?
一张图能非常直观看出 __dict__ 和哈希表的区别。
评论(0)