1. 理解问题:Python对象的默认行为
在Python中,默认情况下对象使用字典(__dict__
)存储实例属性:
class RegularUser:
def __init__(self, name, age):
self.name = name
self.age = age
# 实例化对象
user1 = RegularUser("Alice", 30)
# 动态添加属性(灵活性)
user1.email = "[email protected]"
# 查看实例字典
print(user1.__dict__)
# 输出: {'name': 'Alice', 'age': 30, 'email': '[email protected]'}
内存开销分析:
import sys
print(f"单个实例内存: {
sys.getsizeof(user1) + sys.getsizeof(user1.__dict__)} bytes")
# 输出: 160 bytes (64位Python3.10)
当创建大量对象时,这种灵活性带来的内存开销极其显著:
# 创建百万对象内存测试
instances = [RegularUser(f"User{
i}", i % 100) for i in range(1_000_000)]
print(f"百万对象总内存: {
sum(
sys.getsizeof(i) + sys.getsizeof(i.__dict__)
for i in instances
) / 1024**2:.2f} MB")
# 输出: ~152.22 MB
2. __slots__
基础:声明式属性限制
2.1 基本使用
class SlotUser:
__slots__ = ['name', 'age'] # 预先声明允许的属性
def __init__(self, name, age):
self.name = name
self.age = age
slot_user = SlotUser("Bob", 25)
2.2 核心特性:
-
禁用实例字典:
hasattr(slot_user, '__dict__') # 输出: False
-
禁止动态属性:
try: slot_user.email = "[email protected]" # 触发AttributeError except AttributeError as e: print(e) # 'SlotUser' object has no attribute 'email'
-
内存优化:
print(f"Slot实例内存: { sys.getsizeof(slot_user)} bytes") # 输出: 48 bytes (比常规实例减少70%)