python中的容器和对象
一.对象(Object)
在 Python 中,一切皆对象。对象是 Python 编程的基本单元,具有以下核心特性:
# 所有元素都是对象
num = 42 # 整数对象
s = "hello" # 字符串对象
def func(): pass # 函数对象
class MyClass: pass # 类对象
对象三要素
身份(Identity):对象的唯一标识(内存地址)
print(id(num)) # 输出内存地址,如 140736538677184
类型(Type):决定对象的操作和行为
print(type(num)) # <class 'int'>
值(Value):对象存储的实际数据
二. 容器(Container)
容器是一种特殊对象,用于组织和管理其他对象(元素)。核心特征:
包含关系:可包含一个或多个对象
访问接口:提供访问内部元素的方法
迭代支持:可通过循环遍历内容
常见容器类型:
容器类型 | 特性 | 示例 |
---|---|---|
列表(List) | 可变有序序列 | [1, 'a', 3.14] |
元组(Tuple) | 不可变有序序列 | (1, 'b', True) |
字典(Dict) | 键值对映射 | {'name': 'Alice', 'age': 30} |
集合(Set) | 唯一元素集合 | {1, 2, 3} |
字符串(Str) | 字符序列 | "Python" |
三.关键概念关系
1. 容器即对象
所有容器都是对象,具有对象的全部特性:
my_list = [1, 2, 3]
print(isinstance(my_list, object)) # True
print(type(my_list)) # <class 'list'>
print(id(my_list)) # 内存地址
2. 容器存储对象引用
容器实际存储的是对元素的引用(内存地址),而非对象本身:
a = [1, 2]
b = [a, 3] # b[0] 存储的是列表a的引用
print(b) # [[1, 2], 3]a.append(99)
print(b) # [[1, 2, 99], 3] # b中引用的a同步变化
3. 可变 vs 不可变容器
类型 | 特点 | 示例 |
---|---|---|
可变容器 | 内容可修改 | 列表、字典、集合 |
不可变容器 | 创建后内容不可变 | 元组、字符串、frozenset |
# 可变容器示例
lst = [1, 2]
lst[0] = 99 # 允许修改# 不可变容器示例
tup = (1, 2)
# tup[0] = 99 # 报错: TypeError
四.浅拷贝 vs 深拷贝
拷贝方式 | 特点 | 方法 |
---|---|---|
浅拷贝 | 只复制容器本身,不复制内容 | copy.copy() |
深拷贝 | 递归复制容器及其所有内容 | copy.deepcopy() |
import copy# 浅拷贝示例
orig = [[1,2], [3,4]]
shallow = copy.copy(orig)
orig[0][0] = 99
print(shallow) # [[99,2], [3,4]] # 内部列表被修改# 深拷贝示例
deep = copy.deepcopy(orig)
orig[1][0] = 88
print(deep) # [[99,2], [3,4]] # 完全独立
五.容器对象和常用对象的区别
容器对象是一种特殊的数据结构对象,其主要目的是存储和管理其他对象(元素),它可以包含零个、一个或多个其他对象(这些对象可以是基本类型,也可以是其他复杂对象)。在面向对象语言中,这些容器本身都是用类定义的,实例化后就是对象。它们拥有状态(存储的元素)和行为(操作元素的方法)。
“容器就是容器对象” 在编程中意味着:容器是一种特定类型的对象,它的核心职责是作为其他对象的持有者和管理者,提供标准化的方式来存储、组织和访问这些对象。
1. 本质区别
特征 | 普通对象 | 容器对象 |
---|---|---|
核心目的 | 表示单个实体或概念 | 管理多个对象的集合 |
数据模型 | 封装单一实体的属性和行为 | 封装对象集合的操作逻辑 |
操作接口 | 通过方法和属性访问 | 支持集合操作(索引、迭代等) |
魔术方法 | __init__ , __str__ 等基本方法 | 额外实现容器协议方法 |
与Python生态 | 独立实体 | 可无缝集成到Python集合生态 |
2. 设计哲学对比
普通对象
class BankAccount:"""普通对象:表示银行账户实体"""def __init__(self, account_id, balance=0):self.account_id = account_idself.balance = balancedef deposit(self, amount):self.balance += amountdef withdraw(self, amount):if amount <= self.balance:self.balance -= amountreturn Truereturn Falsedef __str__(self):return f"账户 {self.account_id} 余额: ¥{self.balance}"# 使用场景:操作单个实体
acc1 = BankAccount("A001", 1000)
acc1.deposit(500)
print(acc1) # 账户 A001 余额: ¥1500
容器对象
class Bank:"""容器对象:管理多个银行账户"""def __init__(self):self.accounts = {}# 容器协议实现def __len__(self):return len(self.accounts)def __getitem__(self, account_id):return self.accounts[account_id]def __setitem__(self, account_id, account):self.accounts[account_id] = accountdef __delitem__(self, account_id):del self.accounts[account_id]def __iter__(self):return iter(self.accounts.values())def __contains__(self, account_id):return account_id in self.accounts# 业务方法def total_balance(self):return sum(acc.balance for acc in self.accounts.values())# 使用场景:管理账户集合
bank = Bank()
bank["A001"] = BankAccount("A001", 1000) # __setitem__
bank["A002"] = BankAccount("A002", 2000)print(f"账户数量: {len(bank)}") # __len__ → 2
print(f"总余额: ¥{bank.total_balance()}") # 3000# 遍历所有账户 (__iter__)
for account in bank:print(account)# 访问特定账户 (__getitem__)
print(bank["A001"]) # 账户 A001 余额: ¥1000# 检查账户存在 (__contains__)
print("A003" in bank) # False
总结:dict等内置容器类型确实可以看作是一个类
它们是类:dict、list、set等都是类,位于builtins模块中
可以实例化:通过调用它们来创建实例(对象)
支持继承:可以作为基类被其他类继承
有类属性和方法:拥有__name__、__bases__等类属性
遵循类的规则:支持isinstance、issubclass等检查