
文章目录
-
- 一、什么是多态?
-
- [1.1 多态的核心思想](#1.1 多态的核心思想)
- [1.2 多态的类型](#1.2 多态的类型)
- 二、继承式多态
-
- [2.1 基本实现](#2.1 基本实现)
- [2.2 抽象基类实现多态](#2.2 抽象基类实现多态)
- 三、鸭子类型多态
-
- [3.1 鸭子类型原理](#3.1 鸭子类型原理)
- [3.2 鸭子类型的高级应用](#3.2 鸭子类型的高级应用)
- 四、运算符多态
-
- [4.1 算术运算符多态](#4.1 算术运算符多态)
- [4.2 比较运算符多态](#4.2 比较运算符多态)
- 五、函数和内置函数的多态
-
- [5.1 len()函数的多态](#5.1 len()函数的多态)
- [5.2 内置函数的多态](#5.2 内置函数的多态)
- 六、多态的实际应用场景
-
- [6.1 插件系统](#6.1 插件系统)
- [6.2 策略模式](#6.2 策略模式)
- [6.3 日志系统](#6.3 日志系统)
- 七、多态的优缺点和最佳实践
-
- [7.1 多态的优缺点对比](#7.1 多态的优缺点对比)
- [7.2 多态最佳实践](#7.2 多态最佳实践)
- 八、总结
-
- [8.1 多态的核心要点](#8.1 多态的核心要点)
- [8.2 多态与其他特性的关系](#8.2 多态与其他特性的关系)
一、什么是多态?
多态(Polymorphism)是面向对象编程的三大特性之一(继承、封装、多态)。多态字面意思就是"多种形态",指同一个接口可以有不同的实现方式,或者同一个操作可以作用于不同的对象并产生不同的行为。
1.1 多态的核心思想
- 同一接口,不同实现:同样的方法名在不同类中有不同的实现
- 动态绑定:程序运行时才决定调用哪个方法
- 可替换性:子类对象可以替换父类对象使用
- 扩展性:新增功能不需要修改原有代码
1.2 多态的类型
Python支持两种多态:
- 继承式多态:通过继承和重写实现
- 鸭子类型多态:通过动态类型系统实现
二、继承式多态
2.1 基本实现
python
# 基类(父类)
class Animal:
"""动物基类"""
def __init__(self, name):
self.name = name
def make_sound(self):
"""发出声音(基类方法)"""
return "动物发出声音"
def move(self):
"""移动方式(基类方法)"""
return "动物移动"
# 子类1
class Dog(Animal):
"""狗类"""
def make_sound(self):
"""重写父类方法"""
return f"{self.name}:汪汪汪!"
def move(self):
return f"{self.name}:四条腿奔跑"
# 子类2
class Cat(Animal):
"""猫类"""
def make_sound(self):
return f"{self.name}:喵喵喵~"
def move(self):
return f"{self.name}:悄无声息地走路"
# 子类3
class Bird(Animal):
"""鸟类"""
def make_sound(self):
return f"{self.name}:啾啾啾!"
def move(self):
return f"{self.name}:展翅飞翔"
# 多态函数
def animal_behavior(animal):
"""
演示多态:同一个函数可以处理不同类型的动物
"""
print(animal.make_sound())
print(animal.move())
print("-" * 30)
# 使用示例
if __name__ == "__main__":
# 创建不同类型的动物对象
animals = [
Dog("旺财"),
Cat("咪咪"),
Bird("小鸟")
]
# 统一调用,展现不同行为
for animal in animals:
animal_behavior(animal)
多态调用流程图:
Dog类型
Cat类型
Bird类型
其他类型
调用animal_behavior函数
传入animal对象
animal是什么类型?
调用Dog.make_sound
调用Cat.make_sound
调用Bird.make_sound
调用Animal.make_sound
返回不同结果
2.2 抽象基类实现多态
python
from abc import ABC, abstractmethod
import math
class Shape(ABC):
"""形状抽象基类"""
@abstractmethod
def area(self):
"""计算面积(抽象方法)"""
pass
@abstractmethod
def perimeter(self):
"""计算周长(抽象方法)"""
pass
def description(self):
"""具体方法(所有子类共享)"""
return f"这是一个{self.__class__.__name__},面积:{self.area():.2f},周长:{self.perimeter():.2f}"
class Circle(Shape):
"""圆形"""
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
def perimeter(self):
return 2 * math.pi * self.radius
class Rectangle(Shape):
"""矩形"""
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Triangle(Shape):
"""三角形"""
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def area(self):
# 海伦公式
s = (self.a + self.b + self.c) / 2
return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
def perimeter(self):
return self.a + self.b + self.c
# 多态函数
def print_shape_info(shapes):
"""打印多个形状的信息"""
for shape in shapes:
print(shape.description())
# 使用示例
shapes = [
Circle(5),
Rectangle(4, 6),
Triangle(3, 4, 5)
]
print_shape_info(shapes)
三、鸭子类型多态
3.1 鸭子类型原理
"当看到一只鸟走起来像鸭子、游泳像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"
python
class Duck:
"""鸭子类"""
def quack(self):
return "鸭子嘎嘎叫"
def swim(self):
return "鸭子游泳"
class Person:
"""人类"""
def quack(self):
return "人类模仿鸭子叫"
def swim(self):
return "人类游泳"
class Robot:
"""机器人"""
def quack(self):
return "机器人发出嘎嘎声"
def swim(self):
return "机器人防水游泳"
# 鸭子类型函数:不关心对象类型,只关心是否有相应方法
def make_it_quack(thing):
"""让任何有quack方法的对象叫"""
print(thing.quack())
def make_it_swim(thing):
"""让任何有swim方法的对象游泳"""
print(thing.swim())
# 使用示例
objects = [Duck(), Person(), Robot()]
for obj in objects:
make_it_quack(obj)
make_it_swim(obj)
print("-" * 30)
鸭子类型流程图:
是
否
是
否
传入对象
是否有quack方法?
调用quack方法
抛出AttributeError
是否有swim方法?
调用swim方法
抛出AttributeError
Duck对象
Person对象
Robot对象
3.2 鸭子类型的高级应用
python
class MusicPlayer:
"""音乐播放器"""
def play(self, song):
return f"播放音乐:{song}"
def stop(self):
return "停止播放音乐"
class VideoPlayer:
"""视频播放器"""
def play(self, video):
return f"播放视频:{video}"
def stop(self):
return "停止播放视频"
def subtitle(self):
return "显示字幕"
class GameConsole:
"""游戏机"""
def play(self, game):
return f"运行游戏:{game}"
def stop(self):
return "退出游戏"
def save_progress(self):
return "保存游戏进度"
class MediaController:
"""媒体控制器(使用鸭子类型)"""
def __init__(self):
self.current_device = None
def connect(self, device):
"""连接任何有play和stop方法的设备"""
if hasattr(device, 'play') and hasattr(device, 'stop'):
self.current_device = device
return f"已连接到{device.__class__.__name__}"
else:
raise TypeError("设备必须实现play和stop方法")
def play(self, content):
"""播放内容"""
if self.current_device:
return self.current_device.play(content)
return "没有连接设备"
def stop(self):
"""停止"""
if self.current_device:
return self.current_device.stop()
return "没有连接设备"
# 使用示例
controller = MediaController()
# 连接不同类型的设备
devices = [MusicPlayer(), VideoPlayer(), GameConsole()]
for device in devices:
print(controller.connect(device))
print(controller.play("测试内容"))
print(controller.stop())
# 特定设备特有的方法
if hasattr(device, 'subtitle'):
print(device.subtitle())
if hasattr(device, 'save_progress'):
print(device.save_progress())
print("-" * 30)
四、运算符多态
Python中的运算符实际上是通过特殊方法实现的多态。
4.1 算术运算符多态
python
class Vector2D:
"""二维向量类"""
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
"""重载加法运算符"""
if isinstance(other, Vector2D):
return Vector2D(self.x + other.x, self.y + other.y)
elif isinstance(other, (int, float)):
return Vector2D(self.x + other, self.y + other)
else:
raise TypeError(f"不支持Vector2D和{type(other)}的加法")
def __sub__(self, other):
"""重载减法运算符"""
if isinstance(other, Vector2D):
return Vector2D(self.x - other.x, self.y - other.y)
elif isinstance(other, (int, float)):
return Vector2D(self.x - other, self.y - other)
else:
raise TypeError(f"不支持Vector2D和{type(other)}的减法")
def __mul__(self, scalar):
"""重载乘法运算符"""
if isinstance(scalar, (int, float)):
return Vector2D(self.x * scalar, self.y * scalar)
raise TypeError(f"不支持Vector2D和{type(scalar)}的乘法")
def __rmul__(self, scalar):
"""右乘法(处理 scalar * vector)"""
return self.__mul__(scalar)
def __abs__(self):
"""重载绝对值运算符"""
return (self.x ** 2 + self.y ** 2) ** 0.5
def __str__(self):
return f"Vector2D({self.x}, {self.y})"
def __repr__(self):
return f"Vector2D({self.x}, {self.y})"
class ComplexNumber:
"""复数类"""
def __init__(self, real, imag):
self.real = real
self.imag = imag
def __add__(self, other):
"""复数加法"""
if isinstance(other, ComplexNumber):
return ComplexNumber(self.real + other.real, self.imag + other.imag)
elif isinstance(other, (int, float)):
return ComplexNumber(self.real + other, self.imag)
else:
raise TypeError(f"不支持ComplexNumber和{type(other)}的加法")
def __mul__(self, other):
"""复数乘法"""
if isinstance(other, ComplexNumber):
real = self.real * other.real - self.imag * other.imag
imag = self.real * other.imag + self.imag * other.real
return ComplexNumber(real, imag)
elif isinstance(other, (int, float)):
return ComplexNumber(self.real * other, self.imag * other)
else:
raise TypeError(f"不支持ComplexNumber和{type(other)}的乘法")
def __abs__(self):
"""复数的模"""
return (self.real ** 2 + self.imag ** 2) ** 0.5
def __str__(self):
sign = '+' if self.imag >= 0 else '-'
return f"{self.real} {sign} {abs(self.imag)}i"
# 多态演示
print("=== 运算符多态演示 ===")
v1 = Vector2D(3, 4)
v2 = Vector2D(1, 2)
print(f"v1 + v2 = {v1 + v2}")
print(f"v1 - v2 = {v1 - v2}")
print(f"v1 * 3 = {v1 * 3}")
print(f"2 * v1 = {2 * v1}")
print(f"|v1| = {abs(v1)}")
print("\n=== 复数运算 ===")
c1 = ComplexNumber(3, 4)
c2 = ComplexNumber(1, -2)
print(f"c1 + c2 = {c1 + c2}")
print(f"c1 * c2 = {c1 * c2}")
print(f"|c1| = {abs(c1)}")
4.2 比较运算符多态
python
class Person:
"""人员类"""
def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
def __lt__(self, other):
"""小于比较(按年龄)"""
if isinstance(other, Person):
return self.age < other.age
return NotImplemented
def __le__(self, other):
"""小于等于"""
if isinstance(other, Person):
return self.age <= other.age
return NotImplemented
def __gt__(self, other):
"""大于比较"""
if isinstance(other, Person):
return self.age > other.age
return NotImplemented
def __ge__(self, other):
"""大于等于"""
if isinstance(other, Person):
return self.age >= other.age
return NotImplemented
def __eq__(self, other):
"""等于比较"""
if isinstance(other, Person):
return self.age == other.age and self.name == other.name
return False
def __ne__(self, other):
"""不等于"""
return not self.__eq__(other)
def __str__(self):
return f"{self.name}({self.age}岁)"
# 创建人员列表
people = [
Person("张三", 25, 8000),
Person("李四", 30, 10000),
Person("王五", 22, 6000),
Person("赵六", 28, 9000)
]
# 多态排序(使用自定义的比较运算符)
print("按年龄排序:")
sorted_people = sorted(people)
for person in sorted_people:
print(person)
# 多态比较
print(f"\n张三是否小于李四? {people[0] < people[1]}")
print(f"王五是否大于赵六? {people[2] > people[3]}")
print(f"张三是否等于自己? {people[0] == Person('张三', 25, 8000)}")
五、函数和内置函数的多态
5.1 len()函数的多态
python
class CustomList:
"""自定义列表类"""
def __init__(self, items):
self.items = items
def __len__(self):
"""实现__len__方法使对象支持len()函数"""
return len(self.items)
def __getitem__(self, index):
return self.items[index]
class MultiLevelList:
"""多层列表"""
def __init__(self, *layers):
self.layers = layers
def __len__(self):
"""返回总元素个数"""
total = 0
for layer in self.layers:
total += len(layer)
return total
# len()函数可以作用于不同类型的对象
print("=== len()函数的多态 ===")
print(f"字符串长度:{len('Hello')}")
print(f"列表长度:{len([1, 2, 3, 4])}")
print(f"字典长度:{len({'a':1, 'b':2})}")
print(f"自定义列表长度:{len(CustomList([1,2,3,4,5]))}")
print(f"多层列表长度:{len(MultiLevelList([1,2], [3,4,5], [6,7,8,9]))}")
5.2 内置函数的多态
python
class DataAnalyzer:
"""数据分析器"""
def __init__(self, data):
self.data = data
def __iter__(self):
"""使对象可迭代"""
return iter(self.data)
def __contains__(self, item):
"""使对象支持in操作符"""
return item in self.data
def __reversed__(self):
"""使对象支持reversed()函数"""
return reversed(self.data)
def __str__(self):
return f"DataAnalyzer({self.data})"
class RangeSequence:
"""范围序列"""
def __init__(self, start, end, step=1):
self.start = start
self.end = end
self.step = step
self._data = list(range(start, end, step))
def __iter__(self):
return iter(self._data)
def __len__(self):
return len(self._data)
def __getitem__(self, index):
return self._data[index]
def __contains__(self, item):
"""优化包含检查"""
if not isinstance(item, (int, float)):
return False
return (self.start <= item < self.end and
(item - self.start) % self.step == 0)
# 演示各种内置函数的多态行为
print("=== 内置函数多态演示 ===")
# 创建对象
analyzer = DataAnalyzer([10, 20, 30, 40, 50])
sequence = RangeSequence(1, 10, 2)
# iter()函数
print("iter()函数:")
for item in analyzer:
print(f" {item}")
print()
# in运算符
print("in运算符:")
print(f"30 in analyzer? {30 in analyzer}")
print(f"5 in sequence? {5 in sequence}")
print(f"6 in sequence? {6 in sequence}")
print()
# reversed()函数
print("reversed()函数:")
for item in reversed(analyzer):
print(f" {item}")
print()
# max()和min()函数
print(f"max(analyzer) = {max(analyzer)}")
print(f"min(sequence) = {min(sequence)}")
print(f"sum(sequence) = {sum(sequence)}")
六、多态的实际应用场景
6.1 插件系统
python
from abc import ABC, abstractmethod
import json
import csv
class DataExporter(ABC):
"""数据导出器基类"""
@abstractmethod
def export(self, data, filename):
"""导出数据"""
pass
@abstractmethod
def get_extension(self):
"""获取文件扩展名"""
pass
class JSONExporter(DataExporter):
"""JSON导出器"""
def export(self, data, filename):
full_name = f"{filename}.{self.get_extension()}"
with open(full_name, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return f"数据已导出到 {full_name}"
def get_extension(self):
return "json"
class CSVExporter(DataExporter):
"""CSV导出器"""
def export(self, data, filename):
full_name = f"{filename}.{self.get_extension()}"
with open(full_name, 'w', newline='', encoding='utf-8') as f:
if data and isinstance(data, list):
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
return f"数据已导出到 {full_name}"
def get_extension(self):
return "csv"
class XMLExporter(DataExporter):
"""XML导出器"""
def export(self, data, filename):
full_name = f"{filename}.{self.get_extension()}"
with open(full_name, 'w', encoding='utf-8') as f:
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
f.write('<data>\n')
for item in data:
f.write(' <item>\n')
for key, value in item.items():
f.write(f' <{key}>{value}</{key}>\n')
f.write(' </item>\n')
f.write('</data>')
return f"数据已导出到 {full_name}"
def get_extension(self):
return "xml"
class ExportManager:
"""导出管理器(使用多态)"""
def __init__(self):
self.exporters = {}
def register_exporter(self, name, exporter):
"""注册导出器"""
if isinstance(exporter, DataExporter):
self.exporters[name] = exporter
return f"已注册导出器:{name}"
raise TypeError("必须继承DataExporter类")
def export_data(self, data, filename, format_type):
"""导出数据"""
if format_type not in self.exporters:
available = ', '.join(self.exporters.keys())
return f"不支持的格式:{format_type},可用格式:{available}"
exporter = self.exporters[format_type]
return exporter.export(data, filename)
# 使用示例
data = [
{"name": "张三", "age": 25, "city": "北京"},
{"name": "李四", "age": 30, "city": "上海"},
{"name": "王五", "age": 28, "city": "广州"}
]
# 创建导出管理器
manager = ExportManager()
# 注册各种导出器
manager.register_exporter("json", JSONExporter())
manager.register_exporter("csv", CSVExporter())
manager.register_exporter("xml", XMLExporter())
# 多态调用
print(manager.export_data(data, "users", "json"))
print(manager.export_data(data, "users", "csv"))
print(manager.export_data(data, "users", "xml"))
6.2 策略模式
python
from abc import ABC, abstractmethod
class PaymentStrategy(ABC):
"""支付策略基类"""
@abstractmethod
def pay(self, amount):
"""支付方法"""
pass
@abstractmethod
def get_name(self):
"""获取支付方式名称"""
pass
class CreditCardPayment(PaymentStrategy):
"""信用卡支付"""
def __init__(self, card_number, cvv, expiry):
self.card_number = card_number[-4:]
self.cvv = cvv
self.expiry = expiry
def pay(self, amount):
# 信用卡支付逻辑
return f"使用信用卡({self.card_number})支付 {amount} 元成功"
def get_name(self):
return "信用卡支付"
class AlipayPayment(PaymentStrategy):
"""支付宝支付"""
def __init__(self, account):
self.account = account
def pay(self, amount):
# 支付宝支付逻辑
return f"使用支付宝账户({self.account})支付 {amount} 元成功"
def get_name(self):
return "支付宝支付"
class WechatPayment(PaymentStrategy):
"""微信支付"""
def __init__(self, open_id):
self.open_id = open_id
def pay(self, amount):
# 微信支付逻辑
return f"使用微信(open_id:{self.open_id[:8]}...)支付 {amount} 元成功"
def get_name(self):
return "微信支付"
class CashPayment(PaymentStrategy):
"""现金支付"""
def pay(self, amount):
return f"使用现金支付 {amount} 元,找零请自理"
def get_name(self):
return "现金支付"
class ShoppingCart:
"""购物车"""
def __init__(self):
self.items = []
self.total = 0
def add_item(self, name, price, quantity=1):
self.items.append({
'name': name,
'price': price,
'quantity': quantity,
'subtotal': price * quantity
})
self.total += price * quantity
def checkout(self, payment_strategy):
"""结账(使用多态)"""
if not payment_strategy:
return "请选择支付方式"
if not self.items:
return "购物车是空的"
print("\n=== 购物清单 ===")
for item in self.items:
print(f"{item['name']} x{item['quantity']} = {item['subtotal']}元")
print(f"总计:{self.total}元")
print(f"支付方式:{payment_strategy.get_name()}")
return payment_strategy.pay(self.total)
# 使用示例
cart = ShoppingCart()
cart.add_item("Python编程", 89, 2)
cart.add_item("机械键盘", 399, 1)
cart.add_item("鼠标", 129, 1)
# 使用不同的支付方式
print(cart.checkout(CreditCardPayment("1234567890123456", "123", "12/25")))
print()
print(cart.checkout(AlipayPayment("user@example.com")))
print()
print(cart.checkout(WechatPayment("wx_open_id_123456789")))
print()
print(cart.checkout(CashPayment()))
6.3 日志系统
python
from abc import ABC, abstractmethod
from datetime import datetime
import os
class LogHandler(ABC):
"""日志处理器基类"""
@abstractmethod
def handle(self, message, level):
"""处理日志"""
pass
@abstractmethod
def get_level_name(self, level):
"""获取级别名称"""
pass
class ConsoleLogHandler(LogHandler):
"""控制台日志处理器"""
def __init__(self, show_time=True):
self.show_time = show_time
def handle(self, message, level):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') if self.show_time else ''
level_name = self.get_level_name(level)
if level >= 40: # ERROR级别用红色
color = '\033[91m'
elif level >= 30: # WARNING级别用黄色
color = '\033[93m'
elif level >= 20: # INFO级别用绿色
color = '\033[92m'
else: # DEBUG级别用蓝色
color = '\033[94m'
reset = '\033[0m'
log_line = f"{color}[{level_name}]{reset} {timestamp} - {message}"
print(log_line)
def get_level_name(self, level):
levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
return levels.get(level, 'UNKNOWN')
class FileLogHandler(LogHandler):
"""文件日志处理器"""
def __init__(self, filename='app.log', max_size=1024*1024):
self.filename = filename
self.max_size = max_size
self._check_rotation()
def _check_rotation(self):
"""检查是否需要轮转日志文件"""
if os.path.exists(self.filename):
size = os.path.getsize(self.filename)
if size > self.max_size:
# 简单的日志轮转
base, ext = os.path.splitext(self.filename)
for i in range(9, 0, -1):
old = f"{base}.{i}{ext}"
new = f"{base}.{i+1}{ext}" if i < 9 else f"{base}.{i+1}{ext}"
if os.path.exists(old):
os.rename(old, new)
os.rename(self.filename, f"{base}.1{ext}")
def handle(self, message, level):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
level_name = self.get_level_name(level)
log_line = f"[{level_name}] {timestamp} - {message}\n"
with open(self.filename, 'a', encoding='utf-8') as f:
f.write(log_line)
def get_level_name(self, level):
levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
return levels.get(level, 'UNKNOWN')
class DatabaseLogHandler(LogHandler):
"""数据库日志处理器"""
def __init__(self, connection_string):
self.connection_string = connection_string
self.logs = [] # 模拟数据库
def handle(self, message, level):
timestamp = datetime.now()
level_name = self.get_level_name(level)
log_entry = {
'timestamp': timestamp,
'level': level,
'level_name': level_name,
'message': message
}
self.logs.append(log_entry)
# 模拟数据库写入
print(f"[数据库日志] 已写入 {len(self.logs)} 条记录")
def get_level_name(self, level):
levels = {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}
return levels.get(level, 'UNKNOWN')
def query_logs(self, level=None, limit=10):
"""查询日志"""
results = self.logs
if level:
results = [log for log in results if log['level'] == level]
return results[-limit:]
class Logger:
"""日志器(使用多态)"""
def __init__(self, name):
self.name = name
self.handlers = []
def add_handler(self, handler):
if isinstance(handler, LogHandler):
self.handlers.append(handler)
def log(self, level, message):
for handler in self.handlers:
handler.handle(f"[{self.name}] {message}", level)
def debug(self, message):
self.log(10, message)
def info(self, message):
self.log(20, message)
def warning(self, message):
self.log(30, message)
def error(self, message):
self.log(40, message)
def critical(self, message):
self.log(50, message)
# 使用示例
logger = Logger("MyApp")
# 添加多个处理器
logger.add_handler(ConsoleLogHandler())
logger.add_handler(FileLogHandler("myapp.log"))
logger.add_handler(DatabaseLogHandler("mysql://localhost/logs"))
# 记录日志
logger.debug("这是调试信息")
logger.info("用户登录成功")
logger.warning("磁盘空间不足")
logger.error("数据库连接失败")
logger.critical("系统崩溃")
# 查询数据库日志
db_handler = logger.handlers[2] # 获取数据库处理器
print("\n最近5条数据库日志:")
for log in db_handler.query_logs(limit=5):
print(f" {log['level_name']}: {log['message']}")
七、多态的优缺点和最佳实践
7.1 多态的优缺点对比
python
class PolymorphismDemo:
"""
多态优缺点演示
"""
# 优点:扩展性
def demonstrate_extensibility(self):
"""演示多态的扩展性"""
class Animal:
def speak(self):
return "动物叫"
class Dog(Animal):
def speak(self):
return "汪汪汪"
class Cat(Animal):
def speak(self):
return "喵喵喵"
# 新增一个动物类,不需要修改原有代码
class Duck(Animal):
def speak(self):
return "嘎嘎嘎"
animals = [Dog(), Cat(), Duck()]
for animal in animals:
print(animal.speak())
# 优点:可维护性
def demonstrate_maintainability(self):
"""演示多态的可维护性"""
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, r):
self.r = r
def area(self):
return 3.14 * self.r ** 2
class Rectangle(Shape):
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
# 修改面积计算方式时,只需要修改对应类
# 调用代码完全不需要修改
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print(f"面积:{shape.area()}")
# 缺点:性能开销
def demonstrate_overhead(self):
"""演示多态的性能开销"""
import time
# 使用多态
class Processor:
def process(self, data):
return data * 2
class FastProcessor(Processor):
def process(self, data):
return data * 2
# 直接调用
start = time.time()
p = Processor()
for i in range(1000000):
result = p.process(i)
direct_time = time.time() - start
# 多态调用
start = time.time()
p = FastProcessor()
for i in range(1000000):
result = p.process(i)
polymorphic_time = time.time() - start
print(f"直接调用时间:{direct_time:.4f}秒")
print(f"多态调用时间:{polymorphic_time:.4f}秒")
print(f"性能差异:{(polymorphic_time/direct_time-1)*100:.2f}%")
# 缺点:调试复杂性
def demonstrate_complexity(self):
"""演示多态的调试复杂性"""
class Base:
def method(self):
return "Base"
class A(Base):
def method(self):
return "A"
class B(Base):
def method(self):
return "B"
class C(A, B): # 多重继承
pass
obj = C()
# 需要追踪方法解析顺序
print(f"方法解析顺序:{C.__mro__}")
print(f"调用结果:{obj.method()}")
# 使用示例
demo = PolymorphismDemo()
print("=== 扩展性演示 ===")
demo.demonstrate_extensibility()
print("\n=== 可维护性演示 ===")
demo.demonstrate_maintainability()
print("\n=== 性能开销演示 ===")
demo.demonstrate_overhead()
print("\n=== 调试复杂性演示 ===")
demo.demonstrate_complexity()
7.2 多态最佳实践
python
from abc import ABC, abstractmethod
from typing import List, Union
class DataProcessor(ABC):
"""
数据处理器基类(最佳实践示例)
"""
def __init__(self, name: str):
self.name = name
self._processed_count = 0
@abstractmethod
def process(self, data):
"""处理数据(抽象方法)"""
pass
def get_stats(self) -> dict:
"""获取统计信息(具体方法)"""
return {
'processor_name': self.name,
'processed_count': self._processed_count,
'processor_type': self.__class__.__name__
}
def _increment_count(self):
"""增加处理计数(保护方法)"""
self._processed_count += 1
class TextProcessor(DataProcessor):
"""文本处理器"""
def __init__(self, name="文本处理器"):
super().__init__(name)
self.encoding = 'utf-8'
def process(self, data):
if not isinstance(data, str):
data = str(data)
# 文本处理逻辑
result = data.upper()
self._increment_count()
return result
class NumberProcessor(DataProcessor):
"""数字处理器"""
def __init__(self, name="数字处理器", multiplier=2):
super().__init__(name)
self.multiplier = multiplier
def process(self, data):
if not isinstance(data, (int, float)):
try:
data = float(data)
except (ValueError, TypeError):
return 0
result = data * self.multiplier
self._increment_count()
return result
class ListProcessor(DataProcessor):
"""列表处理器"""
def __init__(self, name="列表处理器"):
super().__init__(name)
self.max_items = 100
def process(self, data):
if not isinstance(data, (list, tuple)):
if hasattr(data, '__iter__'):
data = list(data)
else:
data = [data]
# 限制列表长度
result = data[:self.max_items]
self._increment_count()
return result
class ProcessingPipeline:
"""
处理管道(多态组合)
"""
def __init__(self):
self.processors: List[DataProcessor] = []
def add_processor(self, processor: DataProcessor):
"""添加处理器"""
if isinstance(processor, DataProcessor):
self.processors.append(processor)
return True
return False
def process_data(self, data):
"""处理数据"""
current_data = data
for processor in self.processors:
try:
current_data = processor.process(current_data)
print(f" [{processor.name}] 处理完成")
except Exception as e:
print(f" [{processor.name}] 处理失败:{e}")
break
return current_data
def get_pipeline_stats(self):
"""获取管道统计信息"""
return [proc.get_stats() for proc in self.processors]
# 使用示例
pipeline = ProcessingPipeline()
# 添加不同类型的处理器
pipeline.add_processor(TextProcessor())
pipeline.add_processor(NumberProcessor(multiplier=3))
pipeline.add_processor(ListProcessor())
# 处理不同类型的数据
test_data = [
"hello world",
42,
[1, 2, 3, 4, 5],
{"key": "value"}
]
print("=== 处理管道演示 ===")
for data in test_data:
print(f"\n处理数据:{data}")
result = pipeline.process_data(data)
print(f"最终结果:{result}")
print("\n=== 管道统计信息 ===")
for stats in pipeline.get_pipeline_stats():
print(stats)
八、总结
8.1 多态的核心要点
python
class PolymorphismSummary:
"""
多态总结类
"""
@staticmethod
def summary():
"""多态总结"""
print("""
========== Python多态特性总结 ==========
1. 多态的定义
- 同一个接口,不同的实现
- 同一个操作作用于不同对象产生不同结果
2. 多态的实现方式
- 继承式多态:通过继承和方法重写
- 鸭子类型:只要有相应方法就可以
- 运算符多态:通过特殊方法实现
3. 多态的优点
- 可扩展性:易于添加新功能
- 可维护性:修改不影响调用方
- 可复用性:代码复用程度高
- 灵活性:动态绑定,运行时决定
4. 多态的注意事项
- 性能开销:动态查找有一定成本
- 调试难度:需要理解继承链
- 设计复杂度:需要合理设计类结构
5. 最佳实践
- 使用抽象基类定义接口
- 遵循里氏替换原则
- 优先考虑组合而非继承
- 合理使用鸭子类型
- 做好异常处理
6. 适用场景
- 插件系统
- 策略模式
- 工厂模式
- 框架设计
- API设计
""")
# 调用总结
PolymorphismSummary.summary()
8.2 多态与其他特性的关系
python
class RelationshipDemo:
"""
多态与封装、继承的关系
"""
class Animal:
"""动物基类"""
def __init__(self, name):
self.__name = name # 封装:私有属性
@property
def name(self): # 封装:属性访问器
return self.__name
def speak(self): # 多态:待重写的方法
raise NotImplementedError("子类必须实现speak方法")
def __str__(self): # 封装:字符串表示
return f"{self.__class__.__name__}({self.__name})"
class Dog(Animal): # 继承
def speak(self): # 多态:重写方法
return f"{self.name} 汪汪汪"
class Cat(Animal): # 继承
def speak(self): # 多态:重写方法
return f"{self.name} 喵喵喵"
@classmethod
def demonstrate(cls):
"""演示三者关系"""
animals = [
cls.Dog("旺财"),
cls.Cat("咪咪")
]
for animal in animals:
# 多态调用
print(animal.speak())
# 封装调用
print(f" 名称:{animal.name}")
print(f" 类型:{type(animal)}")
print(f" 字符串:{animal}")
print()
# 使用示例
RelationshipDemo.demonstrate()
通过以上详细的讲解和丰富的示例,我们可以看到Python的多态特性提供了强大的灵活性和扩展性。多态使得代码更加模块化、易于维护和扩展,是面向对象编程中不可或缺的重要特性。合理使用多态可以让我们的代码更加优雅、灵活和强大。