一、面向对象编程核心概念体系
1.1 OOP四大支柱与实现要素
抽象
类Class
封装
访问控制
继承
代码复用
多态
接口统一
成员变量
成员方法
self机制
私有变量
属性装饰器
1.2 开发思维对比
过程式编程 面向对象编程 关注"怎么做" 关注"谁来做" 函数操作数据 数据与行为结合 适合线性流程 适合复杂系统 数据全局可见 数据受对象保护
二、类与对象深度解析
2.1 类定义标准模板
class MobilePhone :
"""移动设备抽象类
Attributes:
brand: 品牌名称(实例属性)
_imei: 设备唯一标识(私有属性)
os_type: 操作系统类型(类属性)
"""
os_type = "Android"
def __init__ ( self, brand: str , imei: str ) :
"""初始化设备信息
Args:
brand: 品牌名称(长度2-20字符)
imei: 国际移动设备识别码(15位数字)
"""
if not ( 2 <= len ( brand) <= 20 ) :
raise ValueError( "品牌名称长度无效" )
if len ( imei) != 15 or not imei. isdigit( ) :
raise ValueError( "IMEI格式错误" )
self. brand = brand
self. _imei = imei
self. __secret_code = ""
def verify_imei ( self, input_imei: str ) - > bool :
"""验证IMEI码(通过self访问私有属性)"""
return self. _imei == input_imei
@classmethod
def change_os ( cls, new_os: str ) :
"""修改类属性"""
cls. os_type = new_os
2.2 对象实例化过程解析
my_phone = MobilePhone( "HUAWEI" , "123456789012345" )
'''
内存变化过程:
1. 调用__new__方法分配内存空间
2. __init__方法通过self参数初始化对象:
- self.brand = "HUAWEI"
- self._imei = "123456789012345"
3. 返回对象引用给my_phone变量
'''
三、构造方法(__inint__
)
3.1 构造方法的核心作用
class Employee :
def __init__ ( self, name: str , emp_id: str , department: str ) :
"""构造方法三要素:
1. 初始化实例属性
2. 参数验证
3. 建立对象初始状态
"""
if len ( emp_id) != 6 or not emp_id. isdigit( ) :
raise ValueError( "员工ID必须为6位数字" )
self. name = name
self. emp_id = emp_id
self. department = department
self. _salary = 0.0
self. access_card = AccessCard( emp_id)
class AccessCard :
def __init__ ( self, card_id: str ) :
self. card_id = card_id
self. activated = False
3.2 构造方法执行流程
类 __new__方法 __init__方法 对象 调用__new__分配内存 创建空对象 自动调用__init__ 初始化对象状态 返回初始化后的对象 类 __new__方法 __init__方法 对象
3.3 构造方法六大特性
特性1:强制命名规范
class CorrectClass :
def __init__ ( self) :
pass
class ErrorClass :
def initialize ( self) :
pass
特性2:可选的返回值
class ReturnTest :
def __init__ ( self) :
return None
特性3:继承链调用
class Animal :
def __init__ ( self, species: str ) :
self. species = species
print ( f"Animal初始化: { species} " )
class Dog ( Animal) :
def __init__ ( self, name: str , breed: str ) :
super ( ) . __init__( "犬科" )
self. name = name
self. breed = breed
print ( f"Dog初始化: { name} " )
特性4:支持默认参数
class NetworkConfig :
def __init__ ( self,
ip: str = "192.168.1.1" ,
port: int = 8080 ) :
self. ip = ip
self. port = port
default_config = NetworkConfig( )
custom_config = NetworkConfig( "10.0.0.1" , 9000 )
特性5:参数验证
class TemperatureSensor :
def __init__ ( self, current_temp: float ) :
if not ( - 273.15 <= current_temp <= 1000 ) :
raise ValueError( "温度值超出物理可能范围" )
self. temperature = current_temp
self. _unit = "℃"
特性6:复合初始化
class Computer :
def __init__ ( self, cpu_model: str ) :
self. cpu = cpu_model
self. _init_peripherals( )
def _init_peripherals ( self) :
"""初始化外设默认状态"""
self. keyboard = "USB键盘"
self. mouse = "无线鼠标"
self. display = "4K显示器"
3.2构造方法设计模式
3.2.1 工厂模式
class Document :
def __init__ ( self, doc_type: str , content: str ) :
self. type = doc_type
self. content = content
@classmethod
def from_file ( cls, file_path: str ) :
"""替代构造方法:从文件创建"""
with open ( file_path, 'r' ) as f:
content = f. read( )
return cls(
doc_type= file_path. split( '.' ) [ - 1 ] ,
content= content
)
doc1 = Document( "txt" , "Hello World" )
doc2 = Document. from_file( "report.docx" )
3.2.2 建造者模式
class CarBuilder :
def __init__ ( self) :
self. car = Car( )
def set_engine ( self, engine: str ) :
self. car. engine = engine
return self
def set_wheels ( self, count: int ) :
self. car. wheels = count
return self
def build ( self) :
return self. car
class Car :
def __init__ ( self) :
self. engine = None
self. wheels = 0
builder = CarBuilder( )
car = builder. set_engine( "V8" ) . set_wheels( 4 ) . build( )
3.3.3 单例模式
class DatabaseConnection :
_instance = None
def __new__ ( cls, connection_str: str ) :
if not cls. _instance:
cls. _instance = super ( ) . __new__( cls)
cls. _instance. conn = connect( connection_str)
return cls. _instance
def __init__ ( self, connection_str: str ) :
"""虽然__new__控制实例创建,但仍需__init__"""
pass
3.4构造方法最佳实践
3.4.1 初始化层次规范
class ScientificInstrument :
def __init__ ( self, model: str ) :
self. model = model
self. _calibrated = False
self. _init_sensors( )
self. _init_data_logger( )
self. _run_self_test( )
def _init_sensors ( self) :
"""初始化传感器组件"""
self. temperature_sensor = Sensor( "温度" , "℃" )
self. pressure_sensor = Sensor( "压力" , "Pa" )
def _run_self_test ( self) :
"""开机自检"""
if not all ( sensor. ready for sensor in self. sensors) :
raise RuntimeError( "传感器初始化失败" )
3.4.2 参数验证模板
def validate_parameters ( func) :
"""构造方法参数验证装饰器"""
def wrapper ( self, * args, ** kwargs) :
if not args[ 1 ] . isalpha( ) :
raise ValueError( "名称必须全字母" )
return func( self, * args, ** kwargs)
return wrapper
class ValidatedClass :
@validate_parameters
def __init__ ( self, name: str ) :
self. name = name
3.4.3 延迟初始化技术
class LazyInitDemo :
def __init__ ( self, config_path: str ) :
self. config_path = config_path
self. _config = None
@property
def config ( self) :
if self. _config is None :
self. _load_config( )
return self. _config
def _load_config ( self) :
"""实际加载配置"""
with open ( self. config_path) as f:
self. _config = json. load( f)
3.5构造方法常见错误案例
3.5.1 忘记调用父类构造方法
class Base :
def __init__ ( self, x: int ) :
self. x = x
class Derived ( Base) :
def __init__ ( self, y: int ) :
self. y = y
d = Derived( 5 )
print ( d. x)
3.5.2 循环依赖初始化
class A :
def __init__ ( self) :
self. b = B( )
class B :
def __init__ ( self) :
self. a = A( )
3.5.3 可变默认参数陷阱
class Dangerous :
def __init__ ( self, items= [ ] ) :
self. items = items
def add ( self, item) :
self. items. append( item)
d1 = Dangerous( )
d1. add( 1 )
d2 = Dangerous( )
print ( d2. items)
四、self关键字的双重角色
4.1 self的六大核心职责
角色 实现方式 示例代码 对象标识符 方法内访问实例的唯一途径 self.brand
属性载体 承载实例特有的数据状态 self._imei = ...
方法调用枢纽 实现方法间的协同工作 self.__check_security()
生命周期管理者 控制对象从创建到销毁的资源 self.__del__()
动态扩展接口 支持运行时添加属性和方法 self.new_feature = lambda: ...
多态实现基础 通过不同self对象实现行为多样性 obj1.method() vs obj2.method()
4.2 self访问机制图解
[对象内存结构]
+-------------------+
| MobilePhone实例 |
|-------------------|
| brand: "HUAWEI" |
| _imei: "1234..." |
| __secret_code: "" |
+-------------------+
↑
| self引用
+-------------------+
| verify_imei方法 |
|-------------------|
| input_imei参数 |
| return比较结果 |
+-------------------+
4.3 三种典型self使用场景
场景1:属性初始化
def __init__ ( self, name) :
self. name = name
场景2:方法间调用
def call ( self, number) :
self. __check_network( )
print ( f"呼叫 { number} " )
def __check_network ( self) :
if self. signal < 1 :
raise ConnectionError( "信号强度不足" )
场景3:实现链式调用
class MessageBuilder :
def __init__ ( self) :
self. content = [ ]
def add_text ( self, text) :
self. content. append( text)
return self
def add_image ( self, url) :
self. content. append( f"<img src=' { url} '>" )
return self
builder = MessageBuilder( )
html = builder. add_text( "Hello" ) . add_image( "pic.jpg" ) . content
五、成员变量管理策略
5.1 变量类型对照表
变量类型 定义位置 访问方式 生命周期 内存分配 类变量 类顶层 类/实例均可访问 与类共存 单份共享 实例变量 init /方法中仅实例访问 随对象销毁 每个实例独立 保护变量 前缀单下划线 约定不直接访问 同实例变量 同实例变量 私有变量 前缀双下划线 类内部访问 同实例变量 同实例变量
5.2 变量操作最佳实践
class BankAccount :
__interest_rate = 0.03
def __init__ ( self, owner: str ) :
self. owner = owner
self. __balance = 0.0
@classmethod
def set_rate ( cls, new_rate: float ) :
"""类方法修改类变量"""
if not 0 < new_rate < 1 :
raise ValueError( "利率超出合理范围" )
cls. __interest_rate = new_rate
def deposit ( self, amount: float ) :
"""实例方法操作私有变量"""
if amount <= 0 :
raise ValueError( "存款金额必须为正数" )
self. __balance += amount
@property
def balance ( self) :
"""属性访问器保护数据"""
return round ( self. __balance, 2 )
六、成员方法全景图
6.1 方法类型矩阵
方法类型 装饰器 self参数 访问权限 典型应用 实例方法 无 必须 访问所有实例成员 主要业务逻辑 类方法 @classmethod cls 操作类变量 工厂模式、配置修改 静态方法 @staticmethod 无 不能访问实例/类变量 工具函数 魔法方法 无 多种形式 特殊操作 str 、__eq__等抽象方法 @abstractmethod self 需子类实现 定义接口规范
6.2 综合方法示例
class SocialMediaPost :
platform = "未知平台"
def __init__ ( self, content: str ) :
self. content = content
self. __views = 0
def show ( self) - > None :
"""实例方法:展示内容"""
self. __increase_views( )
print ( f" { self. platform} 内容: { self. content} " )
def __increase_views ( self) - > None :
"""私有方法:记录浏览量"""
self. __views += 1
@classmethod
def change_platform ( cls, new_platform: str ) - > None :
"""类方法:修改平台"""
cls. platform = new_platform
@staticmethod
def validate_content ( content: str ) - > bool :
"""静态方法:内容审核"""
return len ( content) <= 1000 and not any ( c in content for c in "!@#$" )
def __str__ ( self) - > str :
"""魔法方法:字符串表示"""
return f"< { self. platform} 帖子: { self. content[ : 20] } ...>"
七、魔术方法(Magic Methods)解析
7.1 常用魔术方法分类表
类别 方法 触发场景 示例 对象表示 __str__
, __repr__
print/交互式显示 print(obj)
数学运算 __add__
, __sub__
运算符操作 obj1 + obj2
比较运算 __eq__
, __lt__
比较操作 obj1 == obj2
容器行为 __len__
, __getitem__
容器操作 len(obj)
, obj[0]
上下文管理 __enter__
, __exit__
with语句块 with obj as f:
属性管理 __getattr__
, __setattr__
属性访问 obj.attr
7.2 核心魔术方法实现示例
class Vector3D :
def __init__ ( self, x: float , y: float , z: float ) :
self. x = x
self. y = y
self. z = z
def __str__ ( self) - > str :
return f"Vector3D( { self. x} , { self. y} , { self. z} )"
def __repr__ ( self) - > str :
return f"<Vector3D x: { self. x} y: { self. y} z: { self. z} >"
def __add__ ( self, other) :
return Vector3D(
self. x + other. x,
self. y + other. y,
self. z + other. z
)
def __mul__ ( self, scalar: float ) :
return Vector3D(
self. x * scalar,
self. y * scalar,
self. z * scalar
)
def __eq__ ( self, other) - > bool :
return ( self. x, self. y, self. z) == ( other. x, other. y, other. z)
def __getitem__ ( self, index: int ) - > float :
return [ self. x, self. y, self. z] [ index]
def __len__ ( self) - > int :
return 3
v1 = Vector3D( 1 , 2 , 3 )
v2 = Vector3D( 4 , 5 , 6 )
print ( v1 + v2)
print ( v1 * 2 )
print ( v1[ 0 ] )
print ( len ( v1) )
八、封装机制深入探讨
8.1 封装实现三级防护
访问级别 命名方式 可见范围 示例 公有成员 无下划线 完全公开 self.value
保护成员 单下划线前缀 类及子类内部 self._protected
私有成员 双下划线前缀 仅类内部 self.__private
8.2 私有变量实现原理
class SecuritySystem :
def __init__ ( self) :
self. __alarm_code = "1234"
def check_code ( self, code: str ) - > bool :
return self. __alarm_code == code
obj = SecuritySystem( )
print ( dir ( obj) )
8.3 属性访问控制最佳实践
class TemperatureSensor :
def __init__ ( self) :
self. _current_temp = 0.0
self. __calibration = 1.0
@property
def temperature ( self) - > float :
"""对外暴露的温度值(应用校准)"""
return self. _current_temp * self. __calibration
@temperature. setter
def temperature ( self, value: float ) :
"""温度值设置器(带范围验证)"""
if not ( - 200 <= value <= 1000 ) :
raise ValueError( "温度值超出合理范围" )
self. _current_temp = value
@property
def calibration ( self) - > float :
"""只读属性"""
return self. __calibration
def adjust_calibration ( self, factor: float ) :
"""校准方法(带权限验证)"""
if not ( 0.5 <= factor <= 2.0 ) :
raise ValueError( "校准系数需在0.5-2.0之间" )
self. __calibration = factor
sensor = TemperatureSensor( )
sensor. temperature = 25.5
print ( sensor. temperature)
九、综合案例:银行账户系统
9.1 类设计规范
class BankAccount :
"""银行账户类(演示封装与魔术方法)"""
def __init__ ( self, account_holder: str , initial_balance: float = 0 ) :
self. holder = account_holder
self. __balance = initial_balance
self. __transaction_log = [ ]
def __str__ ( self) - > str :
return f"账户持有人: { self. holder} ,余额:¥ { self. balance: .2f } "
def __repr__ ( self) - > str :
return f"<BankAccount { self. holder[ : 3] } ***>"
def __add__ ( self, amount: float ) :
"""支持 + 运算符存款"""
self. deposit( amount)
return self
@property
def balance ( self) - > float :
"""余额只读属性"""
return self. __balance
def deposit ( self, amount: float ) :
"""存款操作"""
if amount <= 0 :
raise ValueError( "存款金额必须为正数" )
self. __balance += amount
self. __log_transaction( f"存款 ¥ { amount: .2f } " )
def withdraw ( self, amount: float ) :
"""取款操作"""
if amount <= 0 :
raise ValueError( "取款金额必须为正数" )
if amount > self. __balance:
raise ValueError( "余额不足" )
self. __balance -= amount
self. __log_transaction( f"取款 ¥ { amount: .2f } " )
def __log_transaction ( self, message: str ) :
"""私有方法记录交易"""
from datetime import datetime
timestamp = datetime. now( ) . strftime( "%Y-%m-%d %H:%M:%S" )
self. __transaction_log. append( f"[ { timestamp} ] { message} " )
def get_statement ( self) - > str :
"""获取对账单"""
return "\n" . join( self. __transaction_log)
account = BankAccount( "张三" , 1000 )
account += 500
account. withdraw( 300 )
print ( account)
print ( account. get_statement( ) )
十、进阶封装技巧
10.1 动态属性管理
class SmartConfig :
"""动态属性管理示例"""
__allowed_keys = { "timeout" , "retries" , "debug" }
def __init__ ( self) :
self. __data = { }
def __setattr__ ( self, name: str , value) :
"""拦截属性设置"""
if name. startswith( "_" ) :
super ( ) . __setattr__( name, value)
elif name in self. __allowed_keys:
self. __data[ name] = value
else :
raise AttributeError( f"禁止设置属性 { name} " )
def __getattr__ ( self, name: str ) :
"""拦截属性访问"""
if name in self. __data:
return self. __data[ name]
raise AttributeError( f"属性 { name} 不存在" )
def __delattr__ ( self, name: str ) :
"""拦截属性删除"""
if name in self. __data:
del self. __data[ name]
else :
super ( ) . __delattr__( name)
config = SmartConfig( )
config. timeout = 30
10.2 接口隔离原则
from abc import ABC, abstractmethod
class DatabaseConnector ( ABC) :
"""数据库连接器抽象类"""
@abstractmethod
def connect ( self) :
pass
@abstractmethod
def execute_query ( self, sql: str ) :
pass
class MySQLConnector ( DatabaseConnector) :
"""具体实现类"""
def __init__ ( self, host: str ) :
self. __host = host
self. __connection = None
def connect ( self) :
self. __connection = f"连接到 { self. __host} "
def execute_query ( self, sql: str ) :
if not self. __connection:
raise ConnectionError( "请先建立连接" )
print ( f"执行SQL: { sql} " )
connector = MySQLConnector( "localhost" )
connector. connect( )
connector. execute_query( "SELECT * FROM users" )
十一、魔术方法与封装结合实践
11.1 上下文管理器实现
class DatabaseTransaction :
"""数据库事务管理器(演示__enter__/__exit__)"""
def __init__ ( self, db_conn) :
self. conn = db_conn
self. __transaction_active = False
def __enter__ ( self) :
"""进入上下文时启动事务"""
self. conn. execute( "BEGIN TRANSACTION" )
self. __transaction_active = True
return self
def __exit__ ( self, exc_type, exc_val, exc_tb) :
"""退出上下文时提交或回滚"""
if self. __transaction_active:
if exc_type:
self. conn. execute( "ROLLBACK" )
print ( "事务回滚" )
else :
self. conn. execute( "COMMIT" )
print ( "事务提交" )
self. __transaction_active = False
def execute ( self, sql: str ) :
"""执行SQL语句"""
if not self. __transaction_active:
raise RuntimeError( "事务未启动" )
print ( f"执行: { sql} " )
class MockDB :
def execute ( self, cmd) :
print ( f"数据库执行: { cmd} " )
with DatabaseTransaction( MockDB( ) ) as tx:
tx. execute( "INSERT INTO users VALUES (1, 'Alice')" )
tx. execute( "UPDATE accounts SET balance = 100" )
11.2 不可变数据类
class ImmutablePoint :
"""通过封装实现不可变类"""
__slots__ = [ '__x' , '__y' ]
def __init__ ( self, x: float , y: float ) :
self. __x = x
self. __y = y
@property
def x ( self) - > float :
return self. __x
@property
def y ( self) - > float :
return self. __y
def __setattr__ ( self, name, value) :
if name. startswith( "_" ) :
super ( ) . __setattr__( name, value)
else :
raise AttributeError( "不可变对象禁止修改属性" )
def __repr__ ( self) - > str :
return f"Point( { self. x} , { self. y} )"
p = ImmutablePoint( 3 , 4 )
print ( p. x, p. y)
十二、最佳实践总结
12.1 魔术方法使用原则
按需实现 :只实现业务需要的方法保持直观 :运算符重载要符合直觉性能考量 :避免在魔术方法中执行耗时操作文档完善 :清晰说明特殊行为
12.2 封装设计规范
最小暴露原则 :只公开必要接口数据验证前置 :在setter方法中验证输入访问权限分级 :合理使用public/protected/private保持一致性 :类接口设计风格统一
十三、电商系统案例
13.1 类关系设计
1
1
1
*
User
+user_id: str
-_password: str
+cart: ShoppingCart
+add_to_cart()
+checkout()
Product
+sku: str
+price: float
-_stock: int
+restock()
ShoppingCart
-items: dict
+add_item()
+remove_item()
+calculate_total()
13.2 核心代码实现
class Product :
def __init__ ( self, sku: str , name: str , price: float ) :
self. sku = sku
self. name = name
self. price = price
self. _stock = 0
def restock ( self, quantity: int ) - > None :
"""库存补货(通过self维护状态)"""
if quantity <= 0 :
raise ValueError( "补货数量必须为正" )
self. _stock += quantity
@property
def stock_info ( self) - > str :
"""库存状态属性"""
if self. _stock > 100 :
return "充足"
elif self. _stock > 20 :
return "正常"
return "需补货"
class ShoppingCart :
def __init__ ( self) :
self. items = { }
def add_item ( self, product: Product, qty: int = 1 ) - > None :
"""添加商品到购物车"""
if product. _stock < qty:
raise ValueError( f" { product. name} 库存不足" )
self. items[ product] = self. items. get( product, 0 ) + qty
product. _stock -= qty
def total_price ( self) - > float :
"""计算总价(self遍历所有商品)"""
return sum ( p. price * q for p, q in self. items. items( ) )
class User :
def __init__ ( self, user_id: str ) :
self. user_id = user_id
self. cart = ShoppingCart( )
def checkout ( self) - > float :
"""结账操作"""
total = self. cart. total_price( )
self. cart = ShoppingCart( )
return total
iphone = Product( "P1001" , "iPhone 15" , 7999 )
user = User( "U10001" )
user. cart. add_item( iphone, 2 )
print ( f"订单总价:¥ { user. checkout( ) : .2f } " )
print ( iphone. stock_info)
十四、最佳实践与调试技巧
14.1 常见错误排查表
错误现象 可能原因 解决方案 AttributeError 忘记self前缀访问属性 检查所有属性访问是否带self TypeError缺少参数 方法定义遗漏self参数 确保实例方法第一个参数是self 意外修改类变量 通过实例修改类变量 使用类名或cls访问类变量 方法互相覆盖 继承链方法命名冲突 使用super()正确调用父类方法 内存泄漏 循环引用未释放 使用weakref或显式解除引用
14.2 调试技巧
查看对象状态
print ( vars ( user) )
跟踪方法调用
import trace
tracer = trace. Trace( countfuncs= 1 )
tracer. runfunc( user. add_to_cart, product, 2 )
检查类型提示
mypy your_script. py
十五、继承机制深度解析
15.1 继承核心概念
class Vehicle :
"""交通工具基类"""
def __init__ ( self, brand: str , fuel_type: str ) :
self. brand = brand
self. _fuel_type = fuel_type
self. __mileage = 0
def drive ( self, km: float ) - > None :
"""驾驶方法"""
self. __mileage += km
print ( f"行驶 { km} 公里,总里程 { self. __mileage} " )
class ElectricCar ( Vehicle) :
"""电动汽车子类"""
def __init__ ( self, brand: str , battery_cap: float ) :
super ( ) . __init__( brand, "电力" )
self. battery_capacity = battery_cap
def charge ( self, minutes: int ) - > float :
"""充电方法(子类特有)"""
charged = minutes * 0.2
print ( f"已充电 { charged: .1f } 度" )
return charged
def drive ( self, km: float ) - > None :
super ( ) . drive( km)
print ( "零排放驾驶!" )
tesla = ElectricCar( "Tesla" , 75.0 )
tesla. drive( 150 )
15.2 继承类型对比
继承类型 特点 示例 单继承 只有一个直接父类 class A(B): ...
多重继承 多个直接父类 class C(A, B): ...
多级继承 形成继承链 class D(C):
→ C(B)
→ B(A)
接口继承 只继承方法签名(抽象基类) class E(ABC): ...
十六、类型注解全面指南
16.1 基础类型注解
class Student :
school: str = "清华大学"
def __init__ ( self, name: str , age: int ) - > None :
self. name: str = name
self. age: int = age
self. scores: dict [ str , float ] = { }
def add_score ( self, subject: str , score: float ) - > bool :
"""方法参数与返回类型注解"""
if 0 <= score <= 100 :
self. scores[ subject] = score
return True
return False
def get_average ( self) - > float :
"""返回类型注解"""
return sum ( self. scores. values( ) ) / len ( self. scores) if self. scores else 0.0
16.2 高级类型注解技巧
from typing import Union, Optional, List, TypeVar
T = TypeVar( 'T' , bound= 'Animal' )
class Animal :
def speak ( self) - > str :
raise NotImplementedError
class Dog ( Animal) :
def speak ( self) - > str :
return "汪汪!"
class AnimalShelter :
def __init__ ( self) - > None :
self. __animals: List[ Animal] = [ ]
def add_animal ( self, animal: T) - > None :
"""泛型方法注解"""
self. __animals. append( animal)
def find_by_type ( self, animal_type: type [ T] ) - > Optional[ T] :
"""类型参数与返回注解"""
for a in self. __animals:
if isinstance ( a, animal_type) :
return a
return None
shelter = AnimalShelter( )
shelter. add_animal( Dog( ) )
found_dog = shelter. find_by_type( Dog)
if found_dog:
print ( found_dog. speak( ) )
十七、继承与类型注解结合实践
17.1 抽象基类示例
from abc import ABC, abstractmethod
from typing import Protocol
class Drawable ( Protocol) :
"""接口协议定义(Python 3.8+)"""
@abstractmethod
def draw ( self) - > None :
pass
@property
@abstractmethod
def area ( self) - > float :
pass
class Shape ( ABC) :
"""抽象基类"""
def __init__ ( self, color: str ) - > None :
self. color = color
@abstractmethod
def draw ( self) - > None :
pass
@property
@abstractmethod
def area ( self) - > float :
pass
class Circle ( Shape) :
"""具体实现类"""
def __init__ ( self, radius: float , color: str ) - > None :
super ( ) . __init__( color)
self. radius = radius
def draw ( self) - > None :
print ( f"绘制 { self. color} 的圆形,半径 { self. radius} " )
@property
def area ( self) - > float :
return 3.14159 * self. radius ** 2
def render ( shapes: list [ Drawable] ) - > None :
for shape in shapes:
shape. draw( )
print ( f"面积: { shape. area: .2f } " )
render( [ Circle( 5 , "红色" ) ] )
17.2 泛型继承应用
from typing import Generic, TypeVar, List
T = TypeVar( 'T' )
class Repository ( Generic[ T] ) :
"""泛型仓储基类"""
def __init__ ( self) - > None :
self. _items: List[ T] = [ ]
def add ( self, item: T) - > None :
self. _items. append( item)
def get_all ( self) - > List[ T] :
return self. _items. copy( )
class User :
def __init__ ( self, name: str ) - > None :
self. name = name
class UserRepository ( Repository[ User] ) :
"""用户仓储实现"""
def find_by_name ( self, name: str ) - > Optional[ User] :
for user in self. _items:
if user. name == name:
return user
return None
repo = UserRepository( )
repo. add( User( "Alice" ) )
repo. add( User( "Bob" ) )
print ( [ u. name for u in repo. get_all( ) ] )
十八、最佳实践与工具链
18.1 继承设计原则
原则 说明 示例 里氏替换原则 子类应完全实现父类接口 重写方法不修改返回值类型 接口隔离原则 保持接口最小化 使用多个特定接口代替单个大接口 组合优于继承 优先使用组合关系 通过属性包含其他类实例 避免多重继承菱形问题 使用Mixin类代替多重继承 定义可复用功能模块
18.2 类型注解检查工具
mypy静态检查
pip install mypy
mypy your_script.py
Pylance类型提示(VSCode扩展)
{
"python.analysis.typeCheckingMode" : "strict"
}
Pyright检查配置
npm install -g pyright
pyright your_script.py
十九、综合案例:图形系统设计
19.1 类继承结构
«abstract»
Shape
+color: str
+draw()
+area()
Circle
+radius: float
+draw()
+area()
Rectangle
+width: float
+height: float
+draw()
+area()
«mixin»
Movable
+position: tuple[float, float]
+move(dx: float, dy: float)
19.2 类型注解实现
from typing import Protocol, Tuple
class Positional ( Protocol) :
"""位置协议"""
@property
def position ( self) - > Tuple[ float , float ] :
. . .
def move ( self, dx: float , dy: float ) - > None :
. . .
class Shape :
def __init__ ( self, color: str ) - > None :
self. color = color
def draw ( self) - > None :
raise NotImplementedError
@property
def area ( self) - > float :
raise NotImplementedError
class MovableMixin :
"""可移动功能混入类"""
def __init__ ( self) - > None :
self. _position: Tuple[ float , float ] = ( 0.0 , 0.0 )
@property
def position ( self) - > Tuple[ float , float ] :
return self. _position
def move ( self, dx: float , dy: float ) - > None :
self. _position = ( self. _position[ 0 ] + dx, self. _position[ 1 ] + dy)
class Rectangle ( Shape, MovableMixin) :
"""可移动矩形"""
def __init__ ( self, color: str , width: float , height: float ) - > None :
super ( ) . __init__( color)
MovableMixin. __init__( self)
self. width = width
self. height = height
def draw ( self) - > None :
print ( f"在位置 { self. position} 绘制 { self. color} 矩形" )
@property
def area ( self) - > float :
return self. width * self. height
def move_shape ( shape: Positional, dx: float , dy: float ) - > None :
"""使用协议类型注解"""
shape. move( dx, dy)
rect = Rectangle( "蓝色" , 10 , 5 )
move_shape( rect, 2.5 , 3.0 )
rect. draw( )
二十、继承与类型注解注意事项
20.1 继承常见问题
问题 解决方案 父类构造未正确调用 使用super().init ()显式调用 方法重写破坏父类约束 遵循里氏替换原则,保持接口一致性 多重继承顺序冲突 使用方法解析顺序(MRO)检查 过度继承导致耦合 优先使用组合关系替代复杂继承链
20.2 类型注解陷阱
问题 解决方案 循环引用类型提示 使用字符串注解或TypeVar 泛型参数不匹配 明确指定泛型类型参数 动态类型绕过检查 使用强制类型转换或类型保护 第三方库缺少类型提示 添加类型存根文件(.pyi)
学习路线建议
基础阶段
掌握类与对象的关系 理解self的运行机制 区分类变量与实例变量
进阶阶段
高级阶段
设计模式应用(工厂、单例等) 元类编程 实现ORM映射
实战项目