1. 魔法方法详解
魔法方法(Magic Methods)是以双下划线开头和结尾的特殊方法,它们让Python类能够支持内置操作。
小贴士:魔法方法让Python类更加Pythonic,能够自然地集成到Python生态系统中!
__init__ 和 __new__
class Person:
def __new__(cls, name):
print("创建实例")
return super().__new__(cls)
def __init__(self, name):
print("初始化实例")
self.name = name
__str__ 和 __repr__
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"《{self.title}》- {self.author}"
def __repr__(self):
return f"Book('{self.title}', '{self.author}')"
__len__ 和 __getitem__
class ShoppingCart:
def __init__(self):
self.items = []
def __len__(self):
return len(self.items)
def __getitem__(self, index):
return self.items[index]
__call__ 方法
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, value):
return value * self.factor
完整示例:自定义列表类
class SmartList:
"""智能列表类,支持多种操作"""
def __init__(self, items=None):
self.items = items or []
def __len__(self):
return len(self.items)
def __getitem__(self, index):
return self.items[index]
def __setitem__(self, index, value):
self.items[index] = value
def __delitem__(self, index):
del self.items[index]
def __iter__(self):
return iter(self.items)
def __contains__(self, item):
return item in self.items
def __add__(self, other):
return SmartList(self.items + other.items)
def __str__(self):
return f"SmartList({self.items})"
def __repr__(self):
return f"SmartList({self.items})"
def append(self, item):
self.items.append(item)
def extend(self, items):
self.items.extend(items)
# 使用示例
numbers = SmartList([1, 2, 3])
print(len(numbers)) # 3
print(numbers[0]) # 1
numbers[0] = 10
print(numbers) # SmartList([10, 2, 3])
print(2 in numbers) # True
2. 属性描述符详解
描述符(Descriptor)是实现了特定协议的类,可以控制属性的访问、设置和删除。
注意事项:描述符是Python的高级特性,用于创建自定义的属性行为!
2.1 数据描述符
class ValidatedAttribute:
"""验证属性值的描述符"""
def __init__(self, min_value=None, max_value=None):
self.min_value = min_value
self.max_value = max_value
self._values = {}
def __get__(self, instance, owner):
if instance is None:
return self
return self._values.get(instance, None)
def __set__(self, instance, value):
if self.min_value is not None and value < self.min_value:
raise ValueError(f"值必须大于等于 {self.min_value}")
if self.max_value is not None and value > self.max_value:
raise ValueError(f"值必须小于等于 {self.max_value}")
self._values[instance] = value
def __delete__(self, instance):
if instance in self._values:
del self._values[instance]
class Person:
age = ValidatedAttribute(min_value=0, max_value=150)
height = ValidatedAttribute(min_value=0, max_value=300)
# 使用示例
person = Person()
person.age = 25 # 正常
person.height = 175 # 正常
# person.age = -5 # 会抛出 ValueError
2.2 非数据描述符
class LazyProperty:
"""延迟计算属性描述符"""
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
if instance is None:
return self
value = self.func(instance)
setattr(instance, self.func.__name__, value)
return value
class Circle:
def __init__(self, radius):
self.radius = radius
@LazyProperty
def area(self):
print("计算面积...")
return 3.14159 * self.radius ** 2
# 使用示例
circle = Circle(5)
print(circle.area) # 第一次计算
print(circle.area) # 第二次直接使用缓存值
2.3 属性装饰器
class Temperature:
"""温度类,使用属性装饰器"""
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
"""获取摄氏度"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""设置摄氏度"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度")
self._celsius = value
@property
def fahrenheit(self):
"""获取华氏度"""
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
"""设置华氏度"""
self.celsius = (value - 32) * 5/9
@property
def kelvin(self):
"""获取开尔文温度"""
return self._celsius + 273.15
# 使用示例
temp = Temperature(25)
print(temp.celsius) # 25
print(temp.fahrenheit) # 77.0
print(temp.kelvin) # 298.15
temp.fahrenheit = 100
print(temp.celsius) # 37.77777777777778
3. 继承与多态高级
3.1 多重继承与MRO
class Animal:
def speak(self):
return "动物叫声"
class Flyer:
def fly(self):
return "我可以飞"
class Swimmer:
def swim(self):
return "我可以游泳"
class Duck(Animal, Flyer, Swimmer):
def speak(self):
return "嘎嘎"
def __str__(self):
return "鸭子"
# 使用示例
duck = Duck()
print(duck.speak()) # 嘎嘎
print(duck.fly()) # 我可以飞
print(duck.swim()) # 我可以游泳
# 查看方法解析顺序
print(Duck.__mro__)
# (, ,
# , , )
3.2 抽象基类
from abc import ABC, abstractmethod
class Shape(ABC):
"""抽象形状类"""
@abstractmethod
def area(self):
"""计算面积"""
pass
@abstractmethod
def perimeter(self):
"""计算周长"""
pass
def __str__(self):
return f"形状: {self.__class__.__name__}"
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 Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# 使用示例
shapes = [Rectangle(5, 3), Circle(4)]
for shape in shapes:
print(f"{shape}: 面积={shape.area():.2f}, 周长={shape.perimeter():.2f}")
3.3 组合模式
class File:
def __init__(self, name, size):
self.name = name
self.size = size
def get_size(self):
return self.size
class Directory:
def __init__(self, name):
self.name = name
self.contents = []
def add(self, item):
self.contents.append(item)
def remove(self, item):
self.contents.remove(item)
def get_size(self):
return sum(item.get_size() for item in self.contents)
# 使用示例
root = Directory("根目录")
docs = Directory("文档")
docs.add(File("报告.txt", 1024))
docs.add(File("笔记.txt", 512))
root.add(docs)
root.add(File("程序.py", 2048))
print(f"总大小: {root.get_size()} 字节") # 3584
4. 元类基础
元类(Metaclass)是创建类的类,它们控制类的创建过程。
注意事项:元类是Python的极高阶特性,一般只在框架开发中使用!
4.1 简单元类
class SingletonMeta(type):
"""单例模式元类"""
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class DatabaseConnection(metaclass=SingletonMeta):
def __init__(self):
self.connection_id = id(self)
print(f"创建数据库连接: {self.connection_id}")
# 使用示例
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2) # True,只有一个实例
4.2 自动注册类
class AutoRegisterMeta(type):
"""自动注册类的元类"""
registry = {}
def __new__(cls, name, bases, attrs):
new_class = super().__new__(cls, name, bases, attrs)
cls.registry[name.lower()] = new_class
return new_class
class BaseCommand(metaclass=AutoRegisterMeta):
def execute(self):
pass
class CreateCommand(BaseCommand):
def execute(self):
return "创建操作"
class DeleteCommand(BaseCommand):
def execute(self):
return "删除操作"
# 使用示例
print(AutoRegisterMeta.registry)
# {'basecommand': ,
# 'createcommand': ,
# 'deletecommand': }
故事化案例:智能游戏引擎
场景:小李是一名游戏开发者,正在开发一个复杂的角色扮演游戏。他需要创建一个灵活的游戏引擎,支持不同类型的游戏角色、装备系统和技能系统。让我们用类的高级特性来实现这个强大的游戏引擎!
1. 游戏角色系统
class CharacterMeta(type):
"""角色元类,自动注册角色类型"""
def __new__(cls, name, bases, attrs):
new_class = super().__new__(cls, name, bases, attrs)
if not hasattr(cls, 'registry'):
cls.registry = {}
cls.registry[name.lower()] = new_class
return new_class
class GameCharacter(metaclass=CharacterMeta):
"""游戏角色基类"""
def __init__(self, name, level=1):
self.name = name
self.level = level
self._health = 100
self._mana = 50
self._experience = 0
@property
def health(self):
return self._health
@health.setter
def health(self, value):
self._health = max(0, min(value, self.max_health))
@property
def mana(self):
return self._mana
@mana.setter
def mana(self, value):
self._mana = max(0, min(value, self.max_mana))
@property
def max_health(self):
return 100 + self.level * 10
@property
def max_mana(self):
return 50 + self.level * 5
def __str__(self):
return f"{self.__class__.__name__}: {self.name} (等级{self.level})"
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.level})"
class Warrior(GameCharacter):
def __init__(self, name, level=1):
super().__init__(name, level)
self.strength = 15 + level * 3
self.defense = 12 + level * 2
def attack(self):
return f"{self.name} 使用剑击造成 {self.strength} 点伤害"
class Mage(GameCharacter):
def __init__(self, name, level=1):
super().__init__(name, level)
self.intelligence = 18 + level * 4
self.mana *= 1.5
def cast_spell(self):
if self.mana >= 20:
self.mana -= 20
return f"{self.name} 释放火球术造成 {self.intelligence * 1.5} 点魔法伤害"
return f"{self.name} 魔力不足,无法施法"
class Archer(GameCharacter):
def __init__(self, name, level=1):
super().__init__(name, level)
self.agility = 16 + level * 3.5
self.critical_chance = 0.2 + level * 0.02
def shoot_arrow(self):
damage = self.agility * 1.2
if random.random() < self.critical_chance:
damage *= 2
return f"{self.name} 射出暴击箭造成 {damage} 点伤害!"
return f"{self.name} 射出箭矢造成 {damage} 点伤害"
# 使用示例
warrior = Warrior("亚瑟", 5)
mage = Mage("梅林", 4)
archer = Archer("罗宾", 3)
print(warrior)
print(mage)
print(archer)
print(CharacterMeta.registry)
# 查看所有注册的角色类型
2. 装备系统
class EquipmentMeta(type):
"""装备元类,管理装备类型"""
def __new__(cls, name, bases, attrs):
new_class = super().__new__(cls, name, bases, attrs)
if not hasattr(cls, 'equipment_types'):
cls.equipment_types = {}
cls.equipment_types[name.lower()] = new_class
return new_class
class Equipment(metaclass=EquipmentMeta):
"""装备基类"""
def __init__(self, name, rarity="普通"):
self.name = name
self.rarity = rarity
self._enhancement_level = 0
@property
def enhancement_level(self):
return self._enhancement_level
@enhancement_level.setter
def enhancement_level(self, value):
if 0 <= value <= 15:
self._enhancement_level = value
else:
raise ValueError("强化等级必须在0-15之间")
def __str__(self):
rarity_colors = {
"普通": "白色",
"稀有": "蓝色",
"史诗": "紫色",
"传说": "橙色"
}
return f"{rarity_colors.get(self.rarity, '未知')} {self.rarity} {self.name} +{self.enhancement_level}"
def __add__(self, other):
"""装备合成"""
if isinstance(other, Equipment) and self.__class__ == other.__class__:
new_name = f"强化{self.name}"
new_equipment = self.__class__(new_name, self.rarity)
new_equipment.enhancement_level = min(self.enhancement_level + 1, 15)
return new_equipment
raise TypeError("只能合成相同类型的装备")
class Weapon(Equipment):
def __init__(self, name, attack_power, rarity="普通"):
super().__init__(name, rarity)
self.base_attack = attack_power
self.weapon_type = "武器"
@property
def total_attack(self):
return self.base_attack * (1 + self.enhancement_level * 0.1)
class Armor(Equipment):
def __init__(self, name, defense_power, rarity="普通"):
super().__init__(name, rarity)
self.base_defense = defense_power
self.armor_type = "防具"
@property
def total_defense(self):
return self.base_defense * (1 + self.enhancement_level * 0.08)
class Accessory(Equipment):
def __init__(self, name, special_effect, rarity="普通"):
super().__init__(name, rarity)
self.special_effect = special_effect
self.accessory_type = "饰品"
# 使用示例
sword = Weapon("长剑", 100, "史诗")
shield = Armor("圆盾", 50, "稀有")
ring = Accessory("力量戒指", "增加10%攻击力")
print(sword)
print(shield)
print(ring)
# 装备合成
enhanced_sword = sword + sword
print(f"合成后: {enhanced_sword}")
print(f"攻击力: {enhanced_sword.total_attack}")
3. 技能系统
class SkillSystem:
"""技能系统管理器"""
def __init__(self):
self.skills = {}
def register_skill(self, skill_class):
"""注册技能类"""
self.skills[skill_class.__name__.lower()] = skill_class
def create_skill(self, skill_name, *args, **kwargs):
"""创建技能实例"""
if skill_name.lower() in self.skills:
return self.skills[skill_name.lower()](*args, **kwargs)
raise ValueError(f"未知技能: {skill_name}")
class Skill:
"""技能基类"""
def __init__(self, name, mana_cost, cooldown):
self.name = name
self.mana_cost = mana_cost
self.cooldown = cooldown
self._current_cooldown = 0
@property
def is_ready(self):
return self._current_cooldown <= 0
def use(self, caster):
"""使用技能"""
if not self.is_ready:
return f"技能 {self.name} 冷却中 ({self._current_cooldown}回合)"
if caster.mana < self.mana_cost:
return f"魔力不足,无法使用 {self.name}"
caster.mana -= self.mana_cost
self._current_cooldown = self.cooldown
return self.execute(caster)
def execute(self, caster):
"""技能执行逻辑(子类实现)"""
raise NotImplementedError
def tick(self):
"""每回合更新"""
if self._current_cooldown > 0:
self._current_cooldown -= 1
class Fireball(Skill):
def __init__(self):
super().__init__("火球术", 20, 2)
def execute(self, caster):
damage = caster.intelligence * 1.5
return f"{caster.name} 释放火球术造成 {damage} 点魔法伤害"
class Heal(Skill):
def __init__(self):
super().__init__("治疗术", 15, 3)
def execute(self, caster):
heal_amount = caster.intelligence * 2
caster.health += heal_amount
return f"{caster.name} 使用治疗术恢复 {heal_amount} 点生命值"
class Shield(Skill):
def __init__(self):
super().__init__("护盾术", 10, 4)
def execute(self, caster):
shield_amount = caster.defense * 1.2
return f"{caster.name} 激活护盾,获得 {shield_amount} 点护盾值"
# 使用示例
skill_system = SkillSystem()
skill_system.register_skill(Fireball)
skill_system.register_skill(Heal)
skill_system.register_skill(Shield)
mage = Mage("艾莉娅", 10)
fireball = skill_system.create_skill("fireball")
heal = skill_system.create_skill("heal")
print(fireball.use(mage))
print(heal.use(mage))
# 模拟回合
for i in range(5):
fireball.tick()
if i == 2:
print(fireball.use(mage)) # 冷却结束
高级练习题(共5个)
练习题1:观察者模式
使用描述符实现观察者模式,当对象属性发生变化时自动通知观察者。
# 参考答案
class Observable:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def notify_observers(self, name, old_value, new_value):
for observer in self._observers:
observer.update(name, old_value, new_value)
class ObservableAttribute:
def __init__(self, name):
self.name = name
self._values = {}
def __get__(self, instance, owner):
if instance is None:
return self
return self._values.get(instance, None)
def __set__(self, instance, value):
old_value = self._values.get(instance, None)
self._values[instance] = value
if hasattr(instance, 'notify_observers'):
instance.notify_observers(self.name, old_value, value)
class GameCharacter(Observable):
health = ObservableAttribute('health')
mana = ObservableAttribute('mana')
def __init__(self, name):
super().__init__()
self.name = name
class HealthBar:
def update(self, name, old_value, new_value):
if name == 'health':
print(f"血量更新: {old_value} -> {new_value}")
# 使用示例
character = GameCharacter("英雄")
health_bar = HealthBar()
character.add_observer(health_bar)
character.health = 100
character.health = 80
练习题2:状态模式
实现状态模式,让游戏角色能够根据当前状态改变行为。
# 参考答案
class CharacterState:
def handle_attack(self, character):
pass
class NormalState(CharacterState):
def handle_attack(self, character):
return f"{character.name} 正常攻击"
class BuffedState(CharacterState):
def handle_attack(self, character):
return f"{character.name} 强化攻击造成双倍伤害"
class StunnedState(CharacterState):
def handle_attack(self, character):
return f"{character.name} 被眩晕,无法攻击"
class GameCharacter:
def __init__(self, name):
self.name = name
self._state = NormalState()
@property
def state(self):
return self._state
@state.setter
def state(self, new_state):
self._state = new_state
def attack(self):
return self._state.handle_attack(self)
# 使用示例
character = GameCharacter("战士")
print(character.attack())
character.state = BuffedState()
print(character.attack())
character.state = StunnedState()
print(character.attack())
练习题3:策略模式
创建策略模式,让游戏角色能够动态切换战斗策略。
# 参考答案
from abc import ABC, abstractmethod
class AttackStrategy(ABC):
@abstractmethod
def calculate_damage(self, character):
pass
class MeleeStrategy(AttackStrategy):
def calculate_damage(self, character):
return character.strength * 1.2
class MagicStrategy(AttackStrategy):
def calculate_damage(self, character):
return character.intelligence * 1.5
class RangedStrategy(AttackStrategy):
def calculate_damage(self, character):
return character.agility * 1.3
class GameCharacter:
def __init__(self, name, strength=10, intelligence=10, agility=10):
self.name = name
self.strength = strength
self.intelligence = intelligence
self.agility = agility
self.strategy = MeleeStrategy()
def set_strategy(self, strategy):
self.strategy = strategy
def attack(self):
damage = self.strategy.calculate_damage(self)
return f"{self.name} 使用 {self.strategy.__class__.__name__} 造成 {damage} 点伤害"
# 使用示例
character = GameCharacter("英雄")
print(character.attack())
character.set_strategy(MagicStrategy())
print(character.attack())
练习题4:工厂模式
实现工厂模式,动态创建不同类型的游戏对象。
# 参考答案
class GameObjectFactory:
_creators = {}
@classmethod
def register(cls, name):
def decorator(creator_class):
cls._creators[name] = creator_class
return creator_class
return decorator
@classmethod
def create(cls, name, *args, **kwargs):
if name in cls._creators:
return cls._creators[name](*args, **kwargs)
raise ValueError(f"未知对象类型: {name}")
@GameObjectFactory.register("enemy")
class Enemy:
def __init__(self, name, health):
self.name = name
self.health = health
@GameObjectFactory.register("item")
class Item:
def __init__(self, name, value):
self.name = name
self.value = value
@GameObjectFactory.register("npc")
class NPC:
def __init__(self, name, dialogue):
self.name = name
self.dialogue = dialogue
# 使用示例
enemy = GameObjectFactory.create("enemy", "哥布林", 50)
item = GameObjectFactory.create("item", "生命药水", 100)
npc = GameObjectFactory.create("npc", "村长", "欢迎来到村庄!")
练习题5:装饰器模式
实现装饰器模式,动态为游戏角色添加额外能力。
# 参考答案
class CharacterDecorator:
def __init__(self, character):
self.character = character
def attack(self):
return self.character.attack()
class FireEnchantDecorator(CharacterDecorator):
def attack(self):
base_attack = self.character.attack()
return f"{base_attack} 并附加火焰伤害"
class IceEnchantDecorator(CharacterDecorator):
def attack(self):
base_attack = self.character.attack()
return f"{base_attack} 并附加冰霜伤害"
class SpeedBoostDecorator(CharacterDecorator):
def attack(self):
base_attack = self.character.attack()
return f"{base_attack} (速度提升)"
# 使用示例
warrior = Warrior("战士", 10)
decorated_warrior = FireEnchantDecorator(
SpeedBoostDecorator(warrior)
)
print(decorated_warrior.attack())