本文将系统性地探讨 Python 中抽象类与接口的核心差异,通过 ABC 模块实现面向对象设计原则,结合支付系统等真实案例展示架构设计的最佳实践。文末提供完整项目级练习题与答案代码。
from abc import ABC, abstractmethod
class DataExporter(ABC):
@abstractmethod
def export_data(self, data: dict) -> bool:
"""强制子类实现数据导出逻辑"""
def format_size(self, bytes_size: int) -> str:
"""公共方法被子类继承"""
return f"{bytes_size/1024:.2f} KB"
class JSONExporter(DataExporter):
def export_data(self, data):
# 必须实现抽象方法
return json.dumps(data) is not None
关键点:
ABC
元类声明抽象类@abstractmethod
强制方法实现class Loggable(ABC):
@abstractmethod
def write_log(self, message: str) -> None:
pass
class DBConnectable(ABC):
@abstractmethod
def connect(self) -> Connection:
pass
class DatabaseLogger(Loggable, DBConnectable):
def write_log(self, message):
conn = self.connect()
conn.execute("INSERT INTO logs VALUES (?)", (message,))
设计原则:
class PaymentGateway(ABC):
@abstractmethod
def authorize(self, amount: float) -> str:
pass
@abstractmethod
def capture(self, transaction_id: str) -> bool:
pass
@abstractmethod
def refund(self, transaction_id: str, amount: float) -> bool:
pass
class AlipayGateway(PaymentGateway):
def authorize(self, amount):
# 调用支付宝API
return "ALIPAY_2023_TXID"
def capture(self, tx_id):
# 实现具体逻辑
return True
def refund(self, tx_id, amount):
# 支付宝退款实现
return True
class PaymentProcessor:
def __init__(self, gateway: PaymentGateway):
self.gateway = gateway # 依赖抽象
def execute_payment(self, amount):
tx_id = self.gateway.authorize(amount)
if self.gateway.capture(tx_id):
return PaymentResult.success(tx_id)
return PaymentResult.failed()
架构优势:
class ReportGenerator(ABC):
@abstractmethod
def generate_pdf(self) -> bytes:
pass
@abstractmethod
def generate_excel(self) -> bytes:
pass
# 改进后设计
class PDFExportable(ABC):
@abstractmethod
def generate_pdf(self) -> bytes:
pass
class ExcelExportable(ABC):
@abstractmethod
def generate_excel(self) -> bytes:
pass
优化点:
class CompressionStrategy(ABC):
@abstractmethod
def compress(self, data: bytes) -> bytes:
pass
class ZipStrategy(CompressionStrategy):
def compress(self, data):
return zlib.compress(data)
class LZMAStrategy(CompressionStrategy):
def compress(self, data):
return lzma.compress(data)
class FileProcessor:
def __init__(self, strategy: CompressionStrategy):
self.strategy = strategy
def process_file(self, filename):
with open(filename, 'rb') as f:
return self.strategy.compress(f.read())
您的要求非常合理!以下是完整包含 10 个练习题答案 的详细代码实现,每个练习题均给出完整可运行的代码片段:
from abc import ABC, abstractmethod
import json
class PluginBase(ABC):
@abstractmethod
def initialize(self, config: dict) -> None:
"""加载插件配置"""
@abstractmethod
def execute(self, input_data: any) -> any:
"""执行插件核心逻辑"""
class DataCleanPlugin(PluginBase):
def initialize(self, config):
self.rules = config.get('cleaning_rules', [])
def execute(self, data):
# 实现数据清洗逻辑
for rule in self.rules:
data = data.replace(rule['pattern'], rule['replacement'])
return data
class PluginManager:
def __init__(self):
self.plugins = []
def load_plugin(self, plugin: PluginBase):
if not isinstance(plugin, PluginBase):
raise TypeError("插件必须继承 PluginBase")
plugin.initialize({}) # 加载默认配置
self.plugins.append(plugin)
def run_all(self, data):
result = data
for plugin in self.plugins:
result = plugin.execute(result)
return result
# 使用示例
manager = PluginManager()
manager.load_plugin(DataCleanPlugin())
cleaned_data = manager.run_all("原始数据")
from abc import ABC, abstractmethod
import asyncio
class AsyncPaymentGateway(PaymentGateway):
@abstractmethod
async def authorize_async(self, amount: float) -> str:
"""异步授权支付"""
@abstractmethod
async def capture_async(self, tx_id: str) -> bool:
"""异步确认支付"""
class WechatAsyncGateway(AsyncPaymentGateway):
async def authorize_async(self, amount):
await asyncio.sleep(1) # 模拟异步调用
return "WECHAT_ASYNC_TXID"
async def capture_async(self, tx_id):
return True
# 同步方法实现(必须覆盖)
def authorize(self, amount):
raise NotImplementedError("请使用异步接口")
def capture(self, tx_id):
raise NotImplementedError("请使用异步接口")
# 使用示例
async def main():
gateway = WechatAsyncGateway()
tx_id = await gateway.authorize_async(100.0)
success = await gateway.capture_async(tx_id)
asyncio.run(main())
import math
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self) -> float:
pass
class Circle(Shape):
def __init__(self, radius: float):
self.radius = radius
def area(self):
return math.pi * (self.radius ** 2)
class Rectangle(Shape):
def __init__(self, width: float, height: float):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# 使用示例
shapes = [Circle(5), Rectangle(4, 6)]
total_area = sum(shape.area() for shape in shapes)
print(f"Total area: {total_area:.2f}") # 输出:Total area: 110.62
from abc import ABC, abstractmethod
from typing import Protocol
class Connection(Protocol):
def execute(self, query: str) -> None: ...
class ConnectionPool(ABC):
@abstractmethod
def get_connection(self) -> Connection:
"""获取数据库连接"""
@abstractmethod
def release_connection(self, conn: Connection) -> None:
"""释放连接"""
class PostgreSQLPool(ConnectionPool):
def __init__(self, max_connections=5):
self.pool = [self._create_conn() for _ in range(max_connections)]
def _create_conn(self) -> Connection:
# 实际创建连接逻辑
return Connection()
def get_connection(self):
return self.pool.pop()
def release_connection(self, conn):
self.pool.append(conn)
from abc import ABC, abstractmethod
class FileLogger(ABC):
@abstractmethod
def write_to_file(self, message: str) -> None: ...
class DatabaseLogger(ABC):
@abstractmethod
def write_to_db(self, message: str) -> None: ...
class HybridLogger(FileLogger, DatabaseLogger):
def write_to_file(self, message):
with open('log.txt', 'a') as f:
f.write(message + '\n')
def write_to_db(self, message):
# 数据库写入逻辑
pass
# 使用示例
logger = HybridLogger()
logger.write_to_file("Local log")
logger.write_to_db("DB log")
from abc import ABC, abstractmethod
class CompressionStrategy(ABC):
@abstractmethod
def compress(self, data: bytes) -> bytes: ...
class ZipStrategy(CompressionStrategy):
def compress(self, data):
import zlib
return zlib.compress(data)
class AESEncryptionStrategy(CompressionStrategy):
def __init__(self, key: str):
self.key = key
def compress(self, data):
from Crypto.Cipher import AES
cipher = AES.new(self.key.encode(), AES.MODE_EAX)
return cipher.encrypt(data)
class FileProcessor:
def __init__(self, strategy: CompressionStrategy):
self.strategy = strategy
def process(self, data: bytes) -> bytes:
return self.strategy.compress(data)
from abc import ABC, abstractmethod
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> 'Button': ...
@abstractmethod
def create_checkbox(self) -> 'Checkbox': ...
class WindowsFactory(GUIFactory):
def create_button(self):
return WindowsButton()
def create_checkbox(self):
return WindowsCheckbox()
class MacFactory(GUIFactory):
def create_button(self):
return MacButton()
def create_checkbox(self):
return MacCheckbox()
# 产品类定义
class Button(ABC): pass
class WindowsButton(Button): pass
class MacButton(Button): pass
class Checkbox(ABC): pass
class WindowsCheckbox(Checkbox): pass
class MacCheckbox(Checkbox): pass
from abc import ABC, abstractmethod
class TCPState(ABC):
@abstractmethod
def handle_request(self) -> None: ...
class EstablishedState(TCPState):
def handle_request(self):
print("处理已建立连接请求...")
class ListeningState(TCPState):
def handle_request(self):
print("处理监听状态请求...")
class TCPConnection:
def __init__(self):
self.state = ListeningState()
def change_state(self, state: TCPState):
self.state = state
def request(self):
self.state.handle_request()
from abc import ABC, abstractmethod
class DataSource(ABC):
@abstractmethod
def write_data(self, data: str) -> None: ...
class FileDataSource(DataSource):
def write_data(self, data):
with open('data.txt', 'w') as f:
f.write(data)
class DataSourceDecorator(DataSource):
def __init__(self, source: DataSource):
self.wrappee = source
def write_data(self, data):
self.wrappee.write_data(data)
class EncryptionDecorator(DataSourceDecorator):
def write_data(self, data):
encrypted = f"ENCRYPTED({data})"
super().write_data(encrypted)
# 使用示例
source = EncryptionDecorator(FileDataSource())
source.write_data("Sensitive Info") # 写入 ENCRYPTED(Sensitive Info)
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, message: str) -> None: ...
class Subject(ABC):
def __init__(self):
self._observers = []
def attach(self, observer: Observer):
self._observers.append(observer)
def notify(self, message: str):
for obs in self._observers:
obs.update(message)
class EmailNotifier(Observer):
def update(self, message):
print(f"发送邮件通知:{message}")
class SMSNotifier(Observer):
def update(self, message):
print(f"发送短信通知:{message}")
# 使用示例
subject = Subject()
subject.attach(EmailNotifier())
subject.attach(SMSNotifier())
subject.notify("系统升级完成")
pycryptodome
包asyncio.run()
本文深度总结:
掌握这些核心概念,可有效构建符合 SOLID 原则的健壮系统架构。