为什么字典被称为对象:Python 的万物皆对象哲学
## 一、Python 中的"对象"概念
### 1. 一切皆对象
在 Python 中,**所有数据都是对象**,包括:
- 基本数据类型:整数、浮点数、字符串、布尔值
- 数据结构:列表、元组、字典、集合
- 函数和类
- 模块和类型本身
```python
# 验证各种数据都是对象
print(isinstance(42, object)) # True - 整数是对象
print(isinstance("hello", object)) # True - 字符串是对象
print(isinstance([1, 2, 3], object)) # True - 列表是对象
print(isinstance({"a": 1}, object)) # True - 字典是对象
print(isinstance(lambda x: x, object)) # True - 函数是对象
print(isinstance(int, object)) # True - 类型本身也是对象
所有 Python 对象都:
id()
获取的内存地址my_dict = {"name": "John", "age": 30}
print(id(my_dict)) # 身份:唯一标识符
print(type(my_dict)) # 类型:<class 'dict'>
print(my_dict) # 值:{'name': 'John', 'age': 30}
# 检查字典的继承链
print(dict.__mro__) # 显示方法解析顺序
# 输出: (<class 'dict'>, <class 'object'>)
• 在 Python 3 中,所有类都隐式继承自 object,即使没有显式写 class dict(object):。
• 所以 dict.__mro__ 会显示它自己(dict)和它的父类(object)。
表达式 输出 原因
`dict.__mro__` `(dict, object)` `dict` 继承自 `object`
`object.__mro__` `(object,)` `object` 是最顶层基类
# 字典确实是 object 的子类
print(issubclass(dict, object)) # True
字典具备 Python 对象的所有标准特性:
my_dict = {"key": "value"}
# 1. 可以被赋值给变量
another_ref = my_dict
# 2. 可以作为函数参数传递
def process_dict(d):
return len(d)
print(process_dict(my_dict)) # 1
# 3. 可以作为函数返回值
def create_dict():
return {"new": "dict"}
# 4. 可以拥有属性(虽然不常用)
my_dict.custom_attr = "附加属性"
print(my_dict.custom_attr) # 附加属性
# 5. 可以拥有方法
print(my_dict.keys()) # 调用字典方法
print(my_dict.values()) # 调用字典方法
字典具备完整的对象内省能力:
my_dict = {"name": "John", "age": 30}
# 查看对象的所有属性和方法
print(dir(my_dict))
# 输出: ['__class__', '__contains__', '__delattr__', '__delitem__', ...]
# 查看对象的类
print(my_dict.__class__) # <class 'dict'>
# 检查对象是否有特定方法
print(hasattr(my_dict, "get")) # True
print(hasattr(my_dict, "update")) # True
虽然字典是对象,但它们与通过类定义的对象在使用方式和设计目的上有所不同:
# 字典的创建方式
my_dict = {"key": "value"} # 字面量
my_dict = dict(key="value") # 构造函数
my_dict = dict([("key", "value")]) # 从序列创建
# 自定义对象的创建方式
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("John", 30) # 实例化类
# 字典使用方括号访问
my_dict = {"name": "John"}
print(my_dict["name"]) # John
# 自定义对象使用点号访问
class Person:
def __init__(self, name):
self.name = name
person = Person("John")
print(person.name) # John
dict 只是不把“键值对”暴露成同名属性,但它自己仍是一个完整的对象,拥有大量 内置属性与方法:
>>> d = {}
>>> dir(d)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__',
'__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__',
'__setattr__', '__setitem__', '__sizeof__', '__str__',
'__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items',
'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
任何对象(类、实例、甚至模块、函数)都可以使用点号访问属性;
能不能“点”到,取决于该对象有没有实现/继承 属性协议(getattribute/setattr 或描述符)。
类:MyClass.attr
实例:obj.attr
模块:os.path
函数:f.name
只是 dict 选择了 映射协议 (getitem),故意不把键暴露成属性,所以点号找不到键,而不是“只有类对象才能点”。
总结:
键值对 走映射协议,不在实例属性里。
对象自身属性/方法 照常可用,点号随便点。