Python类和对象

🌀 对象即宇宙:Python面向对象编程的终极哲学与架构艺术

“没有对象?Python会为你创建”
当99%开发者还在写’类’时,真正的架构师正在用对象重构数字世界


💫 一、Python对象的本质:超越C++/Java的认知革命

# 你以为的类定义
class User:
    def __init__(self, name):
        self.name = name

# 你不知道的Python对象真相
print(type(User))  # <class 'type'> —— 类本身也是对象!
print(User.__class__)  # <class 'type'>
print(type(1).__class__)  # <class 'type'> —— 万物皆对象!

Python对象模型的颠覆性定位
所有数据都是对象(包括数字、函数、模块、甚至类)
对象即容器:拥有标识(identity)、类型(type)和值(value)
动态性:对象属性可在运行时动态添加/删除(与Java/C++本质不同)

# 对象的动态性实证
from types import SimpleNamespace

user = SimpleNamespace()
user.name = "Alice"
user.role = "developer"
del user.role  # 运行时删除属性

# 甚至可以修改内置类型
int.__subclasses__ = lambda: ["hacked!"]
print(int.__subclasses__())  # 输出 "hacked!" —— 危险但证明了动态性

💡 关键洞察
“Python中不存在原始类型”

  • 1int 类的实例
  • def func():... 会产生 function 类的实例
  • class MyClass: 会产生 type 类的实例

Python的”一切皆对象”是字面意义上的哲学命题


🧱 二、类的深度解剖:超越class的元宇宙

1. 类构建的四层境界

# 境界1:基础类(新手常用)
class BasicUser:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 境界2:带文档的类(团队协作必备)
class DocumentedUser:
    """代表系统中的用户实体
    
    Attributes:
        name: 用户全名(不可为空)
        age: 年龄(18-100)
        _role: 内部角色标识
    """
    
    def __init__(self, name, age):
        ...

# 境界3:类型注解类(IDE友好型)
class TypedUser:
    name: str
    age: int
    _role: str = "user"
    
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

# 境界4:数据类(Python 3.7+的终极形态)
from dataclasses import dataclass

@dataclass(frozen=True, order=True)
class ModernUser:
    name: str
    age: int
    role: str = "user"

Pro技巧
@dataclass 自动生成:

  • __init__
  • __repr__
  • __eq__
  • __lt__(当order=True时)
    减少了70%的样板代码,让类专注表达领域逻辑

2. init vs new:对象诞生的两重门

class MetaSingleton(type):
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        """拦截所有实例化请求"""
        if cls not in cls._instances:
            # __new__ 创建实例
            # __init__ 初始化实例
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Singleton(metaclass=MetaSingleton):
    pass

# 验证单例
a = Singleton()
b = Singleton()
print(a is b)  # True

对象创建生命周期

  1. __new__:负责创建实例(类似构造函数)
    • 静态方法,第一个参数是cls
    • 通常用于不可变类型或元类编程
  2. __init__:负责初始化实例(真正的构造函数)
    • 实例方法,第一个参数是self
    • 不能返回值(或只能返回None

⚠️ 危险警告
滥用 __new__ 会破坏继承体系!
仅当需要控制实例创建过程时使用(如单例、对象池)


🔒 三、封装的艺术:从私有属性到属性描述符

1. 私有属性的真相

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 双下划线触发名称重整
    
    def deposit(self, amount):
        self.__balance += amount
    
    def get_balance(self):
        return self.__balance

account = BankAccount(100)
print(account.get_balance())  # 100

# 尝试直接访问
try:
    print(account.__balance)
except AttributeError:
    # 实际名称已被重整为 _BankAccount__balance
    print(account._BankAccount__balance)  # 100 —— 仍可访问!

封装的Python哲学

“我们都是负责任的成年人”

  • 单下划线 _var:约定为”内部使用”(约定,非强制)
  • 双下划线 __var:触发名称重整(name mangling)_ClassName__var
  • 没有真正的私有属性!但通过约定实现协作式封装

2. @property:将方法伪装为属性

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
    
    @property
    def celsius(self):
        """获取摄氏温度(只读)"""
        return self._celsius
    
    @property
    def fahrenheit(self):
        """动态计算华氏温度"""
        return self._celsius * 9/5 + 32
    
    @fahrenheit.setter
    def fahrenheit(self, value):
        """通过华氏温度设置摄氏温度"""
        self._celsius = (value - 32) * 5/9

temp = Temperature(25)
print(temp.fahrenheit)  # 77.0
temp.fahrenheit = 100
print(temp.celsius)     # 37.777777...

@property的隐藏力量
✅ 保持接口稳定的同时改变内部实现
✅ 添加验证逻辑而不破坏现有调用
✅ 实现计算属性(动态生成值)

💎 大师级技巧

class LazyProperty:
    def __init__(self, func):
        self.func = func
        self.__name__ = func.__name__
    
    def __get__(self, instance, owner):
        if instance is None:
            return self
        value = self.func(instance)
        setattr(instance, self.__name__, value)
        return value

class ExpensiveObject:
    @LazyProperty
    def heavy_computation(self):
        # 模拟耗时计算
        print("Computing...")
        return sum(i*i for i in range(10**6))

obj = ExpensiveObject()
print(obj.heavy_computation)  # 输出 "Computing..." 并返回结果
print(obj.heavy_computation)  # 直接返回缓存结果(无打印)

🧬 四、继承的黑暗面与光明面

1. 多继承的陷阱与救赎

class A:
    def process(self):
        print("A.process")

class B(A):
    def process(self):
        print("B.process")
        super().process()

class C(A):
    def process(self):
        print("C.process")
        super().process()

class D(B, C):
    def process(self):
        print("D.process")
        super().process()

d = D()
d.process()
# 输出:
# D.process
# B.process
# C.process
# A.process

方法解析顺序(MRO)揭秘
D.mro() == [D, B, C, A, object]
Python使用C3线性化算法解决多继承顺序问题,规则:

  1. 子类在父类之前
  2. 保持父类声明顺序
  3. 相同层级的类,先声明的优先

🚨 致命陷阱
不按 “钻石继承” 规范设计:

class X:
    def exec(self):
        print("X.exec")

class Y(X):
    pass

class Z(X):
    def exec(self):
        print("Z.exec")

class W(Y, Z):
    pass

W().exec()  # 输出 "Z.exec" —— 可能不是你期望的!

解决方案:始终通过super()调用,不要硬编码父类名


2. 组合优于继承:现代OOP的基石

# 错误方式:滥用继承
class AdminUser(User):
    def delete_user(self, user_id):
        print(f"Admin deleted user #{user_id}")

class PremiumUser(User):
    def get_discount(self):
        print("20% discount")

# 混合角色时出现问题
class SuperUser(AdminUser, PremiumUser):  # 可能的角色冲突!

# 专业方式:组合与协议
class PermissionProtocol:
    def has_permission(self, permission):
        ...

class Role:
    def __init__(self, name, permissions):
        self.name = name
        self.permissions = set(permissions)

class User:
    def __init__(self, name, roles=None):
        self.name = name
        self.roles = roles or [Role("user", [])]
    
    def has_permission(self, permission):
        return any(permission in role.permissions for role in self.roles)

# 动态分配角色
admin_role = Role("admin", ["delete_user"])
alice = User("Alice", roles=[admin_role])

🌟 OOP设计原则
“继承描述’是什么’,组合描述’有什么’“

  • 继承:表示is-a关系(Student is a Person)
  • 组合:表示has-a关系(Car has an Engine)

🦆 五、多态的Python式实现:鸭子类型的艺术

1. 鸭子类型的精髓

“如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子——不需要继承Duck类”

def process_image(image):
    """接受任何具有'open'和'save'方法的对象"""
    img = image.open()
    img.filter("blur")
    img.save()

# 完全不同的类,但满足协议
class PNGImage:
    def open(self):
        return PNGProcessor()
    def save(self):
        ...

class JPEGImage:
    def open(self):
        return JPEGProcessor()
    def save(self):
        ...

# 甚至可以是字典
process_image({
    "open": lambda: MockProcessor(),
    "save": lambda: print("Saved")
})

鸭子类型的三大优势
✅ 减少不必要的继承
✅ 提高代码灵活性
✅ 促进松耦合设计


2. 抽象基类(ABC):结构化鸭子类型

from abc import ABC, abstractmethod

class Image(ABC):
    @abstractmethod
    def open(self):
        ...
    
    @abstractmethod
    def save(self):
        ...

# 必须实现抽象方法,否则无法实例化
class PNGImage(Image):
    def open(self):
        return PNGProcessor()
    
    # 忘记实现save?——TypeError: Can't instantiate abstract class

# 注册虚拟子类(无需继承)
@Image.register
class DynamicImage:
    def open(self):
        ...
    def save(self):
        ...
    
print(isinstance(DynamicImage(), Image))  # True

🧩 关键场景
需要强制接口实现时用ABC,其他情况优先用鸭子类型

  • 数据模型类(序列、映射)
  • 插件架构的核心协议
  • 严格类型验证的API入口

🔮 六、特殊方法:构建Pythonic对象的魔法

1. 数值操作协议

from functools import total_ordering

@total_ordering
class Vector:
    """可比较、可运算的向量"""
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    # 数值协议
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    # 比较协议(只需实现<=和==)
    def __eq__(self, other):
        return (self.x, self.y) == (other.x, other.y)
    
    def __lt__(self, other):
        return (self.x**2 + self.y**2) < (other.x**2 + other.y**2)

v1 = Vector(2, 3)
v2 = Vector(1, 4)
print(v1 + v2)      # Vector(3, 7)
print(v1 * 2)       # Vector(4, 6)
print(v1 < v2)      # True(因为 2²+3²=13 < 1²+4²=17)

数值协议核心方法
| 用途 | 方法 | |—————|———————–| | 加法 | __add__, __radd__ | | 乘法 | __mul__, __rmul__ | | 比较 | __eq__, __lt__等 | | 真值判断 | __bool__ | | 长度 | __len__ |


2. 容器协议:打造自定义集合

class PriorityQueue:
    """支持优先级的队列"""
    def __init__(self):
        self._items = []
    
    def push(self, item, priority):
        self._items.append((priority, item))
        self._items.sort(reverse=True)  # 高优先级在前
    
    # 容器协议
    def __len__(self):
        return len(self._items)
    
    def __getitem__(self, index):
        """支持下标访问"""
        return self._items[index][1]  # 只返回item
    
    def __iter__(self):
        """支持迭代"""
        for priority, item in self._items:
            yield item
    
    def __contains__(self, item):
        """支持 'in' 操作"""
        return any(i == item for _, i in self._items)

pq = PriorityQueue()
pq.push("task1", 3)
pq.push("task2", 1)
pq.push("task3", 2)

print(len(pq))    # 3
print(pq[0])      # "task1"
for task in pq:   # "task1", "task3", "task2"
    print(task)
print("task2" in pq)  # True

⚙️ 容器协议专家提示
只需实现少量方法,即可获得完整集合行为:

class MyList:
    def __init__(self, items):
        self.items = items
    
    def __getitem__(self, index):
        return self.items[index]
    
    def __len__(self):
        return len(self.items)

# 立即支持切片、迭代、in检查等操作!

🧪 七、面向对象的性能陷阱与优化

1. slots:内存优化大杀器

import sys

class RegularClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class SlottedClass:
    __slots__ = ('x', 'y')  # 定义允许的属性
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 内存对比
regular = RegularClass(1, 2)
slotted = SlottedClass(1, 2)

print(sys.getsizeof(regular))  # ~56字节 + __dict__额外占用
print(sys.getsizeof(slotted))  # ~56字节(无__dict__!)

# 实例属性存储方式
print(hasattr(regular, "__dict__"))  # True
print(hasattr(slotted, "__dict__"))  # False

# 但失去动态属性能力
try:
    slotted.z = 3
except AttributeError:  # 不能添加未声明的属性
    pass

__slots__ 适用场景
✅ 需要创建大量实例的对象(如游戏中的粒子)
✅ 属性固定的高性能数据容器
✅ 内存敏感的核心系统组件

基准测试
100万次实例化的内存消耗:

  • 普通类:≈ 207 MB
  • 带 slots 类:≈ 45 MB (减少78%内存!)

2. new vs init:创建速度的终极对决

import timeit

class FastObject:
    __slots__ = ('name', 'age')
    
    def __new__(cls, name, age):
        self = super(FastObject, cls).__new__(cls)
        self.name = name
        self.age = age
        return self

class NormalObject:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 性能对比
print(timeit.timeit(
    "FastObject('Alice', 30)", 
    "from __main__ import FastObject",
    number=1_000_000
))  # 约 0.15 秒

print(timeit.timeit(
    "NormalObject('Alice', 30)", 
    "from __main__ import NormalObject",
    number=1_000_000
))  # 约 0.23 秒(慢35%!)

对象创建优化矩阵
| 技术 | 内存优化 | 创建速度 | 灵活性 | 适用场景 | |———————|———-|———-|——–|————————| | 普通类 | 基准 | 基准 | 最高 | 通用场景 | | slots | ↑ 70% | ↑ 15% | 降低 | 高频小对象 | | 有__new__的__slots__| ↑ 75% | ↑ 35% | 最低 | 极致性能关键路径 | | namedtuple | ↑ 50% | ↑ 20% | 只读 | 不变数据记录 |


🌐 八、现代OOP架构:从单体到组件化

1. 领域驱动设计(DDD)实现

# 领域模型
class Product:
    def __init__(self, id, name, price):
        self.id = id
        self.name = name
        self.price = price
    
    def apply_discount(self, percentage):
        self.price *= (1 - percentage)
        return self

# 值对象
class Address:
    def __init__(self, street, city, zip_code):
        self.street = street
        self.city = city
        self.zip_code = zip_code
    
    def __eq__(self, other):
        return (self.street, self.city, self.zip_code) == \
               (other.street, other.city, other.zip_code)

# 聚合根
class Order:
    def __init__(self, id, customer_id):
        self.id = id
        self.customer_id = customer_id
        self.items = []
        self._status = "PENDING"
    
    @property
    def status(self):
        return self._status
    
    def add_item(self, product, quantity):
        self.items.append({
            "product": product,
            "quantity": quantity,
            "total": product.price * quantity
        })
    
    def confirm(self):
        if not self.items:
            raise ValueError("Cannot confirm empty order")
        self._status = "CONFIRMED"
        # 触发领域事件
        EventDispatcher.dispatch(OrderConfirmedEvent(self.id))

# 仓储接口
class OrderRepository(ABC):
    @abstractmethod
    def save(self, order: Order):
        pass
    
    @abstractmethod
    def find_by_id(self, id) -> Order:
        pass

# 具体实现
class SQLOrderRepository(OrderRepository):
    def __init__(self, db_connection):
        self.db = db_connection
    
    def save(self, order):
        # 执行SQL保存
        ...

DDD核心思想

  • 模型与实现同步演进
  • 隔离核心领域逻辑
  • 用对象表达业务规则
    “代码即业务文档”

2. 组件化架构:超越继承的组合革命

# 组件基类
class Component:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

# 具体组件
class PhysicsComponent(Component):
    def __init__(self, mass, friction, **kwargs):
        super().__init__(**kwargs)
        self.mass = mass
        self.friction = friction
    
    def update_physics(self, delta_time):
        # 物理模拟逻辑
        ...

class GraphicsComponent(Component):
    def __init__(self, sprite, **kwargs):
        super().__init__(**kwargs)
        self.sprite = sprite
    
    def render(self, screen):
        screen.blit(self.sprite)

# 游戏实体(组合组件)
class Entity:
    def __init__(self, *components):
        self.components = {}
        for comp in components:
            self.add_component(comp)
    
    def add_component(self, component):
        comp_type = type(component)
        self.components[comp_type] = component
    
    def get_component(self, comp_type):
        return self.components.get(comp_type)
    
    def update(self, delta_time):
        if phys := self.get_component(PhysicsComponent):
            phys.update_physics(delta_time)

# 创建游戏对象
player = Entity(
    PhysicsComponent(mass=70, friction=0.8),
    GraphicsComponent(sprite="player.png", layer=2)
)

# 访问组件
physics = player.get_component(PhysicsComponent)
physics.mass *= 1.5  # 增强角色

组件模式优势
✅ 动态修改对象能力(运行时添加/移除组件)
✅ 避免继承层级爆炸
✅ 促进代码复用和模块化
✅ 完美适合游戏开发、GUI系统


🔮 九、高阶OOP:元类与架构魔法

1. 元类实战:自注册工厂

class Registry(type):
    """自动将子类注册到工厂"""
    _registry = {}
    
    def __new__(mcs, name, bases, attrs):
        cls = super().__new__(mcs, name, bases, attrs)
        # 跳过基类注册
        if name != "Model":
            Registry._registry[name.lower()] = cls
        return cls
    
    @classmethod
    def get_model(cls, name):
        return cls._registry[name]

class Model(metaclass=Registry):
    pass

class User(Model):
    pass

class Product(Model):
    pass

# 无需手动注册
print(Registry.get_model("user"))    # <class '__main__.User'>
print(Registry.get_model("product")) # <class '__main__.Product'>

元类执行顺序

  1. 类定义时:
    • 执行类体代码
    • 创建类字典(包含方法和属性)
    • 调用元类的 __new__
    • 调用元类的 __init__
  2. 实例化时:
    • 调用类的 __new__
    • 调用类的 __init__

⚠️ 警告
“元类是99%代码不需要的重型武器”
仅在以下场景使用:

  • 全局注册表(如ORM模型)
  • 框架级架构约束
  • 代码生成/修改(如自动序列化)

2. 描述符协议:属性控制的终极武器

class Typed:
    """强制类型检查的描述符"""
    def __init__(self, type_):
        self.type_ = type_
        self.data = {}
    
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return self.data.get(id(instance))
    
    def __set__(self, instance, value):
        if not isinstance(value, self.type_):
            raise TypeError(f"Expected {self.type_.__name__}")
        self.data[id(instance)] = value
    
    def __delete__(self, instance):
        del self.data[id(instance)]

class Person:
    name = Typed(str)
    age = Typed(int)
    
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("Alice", 30)
p.age = "thirty"  # TypeError: Expected int

描述符类型对比
| 类型 | 触发条件 | 典型应用 | |—————-|——————————|————————| | 数据描述符 | 有__set__或__delete__ | @property, Typed字段 | | 非数据描述符 | 只有__get__ | 普通方法 | | 优先级规则 | 实例字典 > 数据描述符 > 非数据描述符 | 保证属性访问一致性 |


🧪 十、面向对象反模式:躲开这些致命陷阱

1. God Object:万能类的诅咒

# 危险代码!绝不要这样写
class GodClass:
    def __init__(self):
        self.data = {}
    
    def process_order(self): ...
    def send_email(self): ...
    def calculate_tax(self): ...
    def generate_report(self): ...
    def save_to_db(self): ...
    # 200+个其他方法...

God Object的症状
❌ 超过500行代码
❌ 包含不相关的业务逻辑
❌ 修改一处可能破坏其他功能
❌ 测试覆盖率极低

💊 解药配方

  1. 识别界限上下文(用# === DOMAIN BOUNDARY ===标记)
  2. 按职责拆分为领域对象
  3. 使用外观模式(Facade)保持接口简单

2. 继承滥用:脆弱的基类问题

class FileLogger:
    def log(self, message):
        with open("log.txt", "a") as f:
            f.write(message + "\n")

# 某天需要添加时间戳
class TimestampLogger(FileLogger):
    def log(self, message):
        super().log(f"[{time.ctime()}] {message}")  # 修改了行为

# 问题:其他继承FileLogger的类也需要时间戳吗?
class EmailLogger(FileLogger):
    def log(self, message):
        # 期待原始FileLogger行为...
        super().log(message)
        send_email(...)  # 但基类行为已改变!

继承的脆弱性本质
子类过度依赖基类实现细节,基类修改导致”涟漪效应”

专业解决方案

# 使用装饰器模式
class Logger:
    def log(self, message):
        raise NotImplementedError

class FileLogger(Logger):
    def log(self, message):
        ...

class TimestampDecorator(Logger):
    def __init__(self, logger):
        self.logger = logger
    
    def log(self, message):
        self.logger.log(f"[{time.ctime()}] {message}")

# 组合方式应用功能
logger = TimestampDecorator(FileLogger())
logger.log("System started")

🧪 十一、现代OOP工具箱:提升你的架构级别

1. 数据类 vs TypedDict vs 命名元组

from dataclasses import dataclass, field
from typing import TypedDict, NamedTuple
from collections import namedtuple

# 1. 命名元组(不可变,轻量级)
PersonNT = namedtuple("Person", ["name", "age"])

# 2. TypedDict(类型安全的字典替代)
class PersonTD(TypedDict):
    name: str
    age: int

# 3. 数据类(完全对象化)
@dataclass
class PersonDC:
    name: str
    age: int
    hobbies: list = field(default_factory=list)

# 专业对比
alice_nt = PersonNT("Alice", 30)       # 内存最小,不可变
alice_td: PersonTD = {"name": "Alice", "age": 30}  # 类型检查友好
alice_dc = PersonDC("Alice", 30, ["coding"])  # 功能最全

对象建模选择指南
| 场景 | 推荐方案 | |——————————-|——————-| | 不变数据记录 | NamedTuple | | 字典替代品(JSON友好) | TypedDict | | 领域对象/需要方法 | dataclass | | 需要继承/复杂行为 | 普通类 | | 性能关键的小对象 | __slots__类 |


2. 协议类(PEP 544):优雅的类型约束

from typing import Protocol, runtime_checkable

@runtime_checkable
class Drawable(Protocol):
    def draw(self, canvas) -> None:
        ...

class Circle:
    def draw(self, canvas):
        print("Drawing circle")

class Square:
    def render(self, surface):  # 错误方法名
        print("Drawing square")

def render_all(elements: list[Drawable], canvas):
    for elem in elements:
        elem.draw(canvas)  # 类型检查器知道所有元素有draw方法

# 静态类型检查通过
render_all([Circle()], "canvas")

# 运行时检查(可选)
from typing import runtime_checkable
@runtime_checkable
class Drawable(Protocol):
    ...

isinstance(Square(), Drawable)  # False

🔥 协议类优势
无需继承即可实现接口约束
完美支持鸭子类型的同时获得类型安全
替代ABC的轻量级方案(Python 3.8+)


💎 十二、终极测试:面向对象大师挑战

问题1:修复循环依赖

# module_a.py
from module_b import B

class A:
    def __init__(self):
        self.b = B()  # 循环依赖!

# module_b.py
from module_a import A

class B:
    def __init__(self):
        self.a = A()  # 双向依赖导致导入失败

专业解决方案

# module_a.py
class A:
    def __init__(self):
        # 延迟导入解决循环依赖
        from module_b import B
        self.b = B(self)  # 传入自身而非创建新实例

# module_b.py
class B:
    def __init__(self, a_instance):  # 接收现有A实例
        self.a = a_instance

问题2:实现线程安全的观察者模式

class Subject:
    def __init__(self):
        self._observers = []
    
    def attach(self, observer):
        self._observers.append(observer)
    
    def notify(self, data):
        for observer in self._observers:
            observer.update(data)

大师级实现

from threading import RLock
from weakref import WeakSet

class ThreadSafeSubject:
    def __init__(self):
        self._observers = WeakSet()  # 避免内存泄漏
        self._lock = RLock()
    
    def attach(self, observer):
        with self._lock:
            self._observers.add(observer)
    
    def detach(self, observer):
        with self._lock:
            self._observers.discard(observer)
    
    def notify(self, data):
        with self._lock:
            # 复制观察者列表,避免遍历时修改
            observers = list(self._observers)
        
        for observer in observers:
            try:
                observer.update(data)
            except Exception as e:
                # 错误隔离,不影响其他观察者
                print(f"Observer {observer} failed: {e}")

问题3:设计类型安全的领域事件系统

class Event:
    """所有事件的基类"""

class UserCreated(Event):
    def __init__(self, user_id):
        self.user_id = user_id

class EventDispatcher:
    def __init__(self):
        self._handlers = {}
    
    def register(self, event_type, handler):
        # 注册能处理特定事件的函数
        ...
    
    def dispatch(self, event):
        # 通知所有相关处理函数
        ...

专家解决方案

from typing import Type, Dict, List, Callable, TypeVar, Generic

E = TypeVar('E', bound=Event)

class EventHandler(Protocol[E]):
    def __call__(self, event: E) -> None:
        ...

class EventDispatcher:
    def __init__(self):
        self._handlers: Dict[Type[Event], List[Callable]] = {}
    
    def register(self, event_type: Type[E], handler: EventHandler[E]):
        """类型安全的事件注册"""
        if event_type not in self._handlers:
            self._handlers[event_type] = []
        self._handlers[event_type].append(handler)
    
    def dispatch(self, event: Event):
        """只通知能处理该事件的处理器"""
        event_type = type(event)
        for handler in self._handlers.get(event_type, []):
            handler(event)

# 使用示例(带完整类型检查)
dispatcher = EventDispatcher()

def handle_user_created(event: UserCreated):
    print(f"New user created: {event.user_id}")

dispatcher.register(UserCreated, handle_user_created)
dispatcher.dispatch(UserCreated("user123"))  # 类型检查通过
dispatcher.dispatch("not an event")         # 类型检查失败!

🌌 结语:OOP的本质是认知框架

“面向对象不是语法,而是人类理解复杂世界的思维映射”

当你设计类的瞬间:

  • 你定义了问题域的词汇表
  • 你构建了概念间的关系网络
  • 你创造了可组合的认知积木

真正的Python大师领悟

  • 封装是认知边界的显式声明
  • 继承是概念层次的优雅表达
  • 多态是世界复杂性的诗意妥协

下次定义类前,请默念:
“我不是在写代码,
而是在雕刻数字宇宙的认知模型”