继承和多态
本节将介绍Python中的继承和多态概念,这是面向对象编程中实现代码重用和扩展的重要机制。
类的继承
基本继承
class Animal:
"""动物基类"""
def __init__(self, name: str):
self.name = name
def speak(self) -> str:
"""发出声音"""
return "Some sound"
class Dog(Animal):
"""狗类"""
def speak(self) -> str:
"""狗叫"""
return "Woof!"
class Cat(Animal):
"""猫类"""
def speak(self) -> str:
"""猫叫"""
return "Meow!"
# 使用继承
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.name, dog.speak()) # 输出: Buddy Woof!
print(cat.name, cat.speak()) # 输出: Whiskers Meow!
调用父类方法
class Vehicle:
"""车辆基类"""
def __init__(self, brand: str, model: str):
self.brand = brand
self.model = model
def get_info(self) -> str:
"""获取车辆信息"""
return f"{self.brand} {self.model}"
class Car(Vehicle):
"""汽车类"""
def __init__(self, brand: str, model: str, seats: int):
# 调用父类的__init__方法
super().__init__(brand, model)
self.seats = seats
def get_info(self) -> str:
"""获取汽车信息"""
# 调用父类的get_info方法
base_info = super().get_info()
return f"{base_info} ({self.seats} seats)"
# 使用父类方法
car = Car("Toyota", "Camry", 5)
print(car.get_info()) # 输出: Toyota Camry (5 seats)
抽象类和接口
抽象基类
from abc import ABC, abstractmethod
from typing import List, Dict
class LLMClient(ABC):
"""LLM客户端抽象基类"""
@abstractmethod
def chat_completion(
self,
messages: List[Dict[str, str]],
**kwargs
) -> Dict:
"""聊天补全"""
pass
@abstractmethod
def embeddings(
self,
text: str,
**kwargs
) -> List[float]:
"""文本嵌入"""
pass
class OpenAIClient(LLMClient):
"""OpenAI客户端"""
def chat_completion(
self,
messages: List[Dict[str, str]],
**kwargs
) -> Dict:
# 实现OpenAI的聊天补全
return {"choices": [{"message": {"content": "Hello!"}}]}
def embeddings(
self,
text: str,
**kwargs
) -> List[float]:
# 实现OpenAI的文本嵌入
return [0.1, 0.2, 0.3]
# 使用抽象类
client = OpenAIClient()
response = client.chat_completion([
{"role": "user", "content": "Hi!"}
])
多重继承
class Loggable:
"""可记录日志的混入类"""
def log(self, message: str):
"""记录日志"""
print(f"[LOG] {message}")
class Serializable:
"""可序列化的混入类"""
def to_dict(self) -> Dict:
"""转换为字典"""
return self.__dict__
def from_dict(self, data: Dict):
"""从字典加载"""
self.__dict__.update(data)
class APIResponse(Loggable, Serializable):
"""API响应类"""
def __init__(self, status: int, data: Dict):
self.status = status
self.data = data
self.log(f"Response created with status {status}")
def __str__(self) -> str:
return f"Status: {self.status}, Data: {self.data}"
# 使用多重继承
response = APIResponse(200, {"message": "Success"})
print(response.to_dict()) # 使用Serializable的方法
response.log("Processing complete") # 使用Loggable的方法
多态
函数多态
from typing import Union, List
class TextProcessor:
"""文本处理器"""
def process(
self,
text: Union[str, List[str]]
) -> Union[str, List[str]]:
"""处理文本"""
if isinstance(text, str):
return text.upper()
elif isinstance(text, list):
return [t.upper() for t in text]
else:
raise TypeError("Unsupported type")
# 使用多态
processor = TextProcessor()
print(processor.process("hello")) # 输出: HELLO
print(processor.process(["hi", "there"])) # 输出: ['HI', 'THERE']
接口多态
class DataSource(ABC):
"""数据源接口"""
@abstractmethod
def read(self) -> str:
"""读取数据"""
pass
class FileSource(DataSource):
"""文件数据源"""
def __init__(self, filename: str):
self.filename = filename
def read(self) -> str:
with open(self.filename, 'r') as f:
return f.read()
class APISource(DataSource):
"""API数据源"""
def __init__(self, url: str):
self.url = url
def read(self) -> str:
# 模拟API调用
return f"Data from {self.url}"
def process_data(source: DataSource) -> str:
"""处理数据"""
data = source.read()
return data.upper()
# 使用接口多态
file_source = FileSource("data.txt")
api_source = APISource("https://api.example.com/data")
print(process_data(file_source)) # 处理文件数据
print(process_data(api_source)) # 处理API数据
实际应用示例
LLM模型抽象
class BaseModel(ABC):
"""LLM模型基类"""
@abstractmethod
def generate(
self,
prompt: str,
**kwargs
) -> str:
"""生成文本"""
pass
@abstractmethod
def get_embedding(
self,
text: str,
**kwargs
) -> List[float]:
"""获取文本嵌入"""
pass
class GPT3Model(BaseModel):
"""GPT-3模型"""
def __init__(self, api_key: str):
self.client = OpenAIClient(api_key)
def generate(
self,
prompt: str,
**kwargs
) -> str:
response = self.client.chat_completion([
{"role": "user", "content": prompt}
], **kwargs)
return response["choices"][0]["message"]["content"]
def get_embedding(
self,
text: str,
**kwargs
) -> List[float]:
return self.client.embeddings(text, **kwargs)
class ClaudeModel(BaseModel):
"""Claude模型"""
def __init__(self, api_key: str):
self.client = AnthropicClient(api_key)
def generate(
self,
prompt: str,
**kwargs
) -> str:
response = self.client.complete(prompt, **kwargs)
return response["completion"]
def get_embedding(
self,
text: str,
**kwargs
) -> List[float]:
return self.client.embed(text, **kwargs)
# 使用模型抽象
def process_text(
model: BaseModel,
text: str
) -> tuple[str, List[float]]:
"""处理文本"""
response = model.generate(text)
embedding = model.get_embedding(text)
return response, embedding
# 可以使用不同的模型
gpt3 = GPT3Model("openai-key")
claude = ClaudeModel("anthropic-key")
result_gpt3 = process_text(gpt3, "Hello!")
result_claude = process_text(claude, "Hello!")
插件系统
class Plugin(ABC):
"""插件基类"""
@abstractmethod
def name(self) -> str:
"""插件名称"""
pass
@abstractmethod
def process(
self,
text: str
) -> str:
"""处理文本"""
pass
class TranslationPlugin(Plugin):
"""翻译插件"""
def name(self) -> str:
return "translator"
def process(self, text: str) -> str:
# 实现翻译逻辑
return f"Translated: {text}"
class SummaryPlugin(Plugin):
"""摘要插件"""
def name(self) -> str:
return "summarizer"
def process(self, text: str) -> str:
# 实现摘要逻辑
return f"Summary: {text}"
class PluginManager:
"""插件管理器"""
def __init__(self):
self.plugins: Dict[str, Plugin] = {}
def register(self, plugin: Plugin):
"""注册插件"""
self.plugins[plugin.name()] = plugin
def process(
self,
text: str,
plugin_name: str
) -> str:
"""使用指定插件处理文本"""
if plugin_name not in self.plugins:
raise ValueError(f"Plugin {plugin_name} not found")
return self.plugins[plugin_name].process(text)
# 使用插件系统
manager = PluginManager()
manager.register(TranslationPlugin())
manager.register(SummaryPlugin())
text = "Hello, world!"
translated = manager.process(text, "translator")
summarized = manager.process(text, "summarizer")
最佳实践
继承使用:
- 遵循"是一个"关系
- 避免过深的继承层次
- 优先使用组合而非继承
抽象类设计:
- 定义清晰的接口
- 只抽象必要的方法
- 提供适当的默认实现
多态应用:
- 使用依赖注入
- 面向接口编程
- 遵循里氏替换原则
代码复用:
- 使用混入类
- 合理设计类层次
- 避免代码重复
下一步
现在您已经掌握了继承和多态的概念,接下来我们将学习Python的特殊方法和魔术方法。