面试题答案
一键面试场景描述
假设我们正在开发一个游戏框架,其中需要创建各种类型的游戏角色,如战士、法师、刺客等。每个角色都有不同的行为和属性,但它们都继承自一个基类 Character
。同时,我们希望通过元类来自动为每个角色类添加一些通用的功能,例如日志记录功能,记录角色的各种行为(如攻击、防御等)。
元类设计
import logging
class CharacterMeta(type):
def __new__(mcs, name, bases, attrs):
def log_action(func):
def wrapper(self, *args, **kwargs):
logging.info(f"{self.__class__.__name__} is performing {func.__name__}")
return func(self, *args, **kwargs)
return wrapper
for attr_name, attr_value in attrs.items():
if callable(attr_value) and not attr_name.startswith('__'):
attrs[attr_name] = log_action(attr_value)
return super().__new__(mcs, name, bases, attrs)
这个元类 CharacterMeta
会遍历类的属性,对于所有非特殊方法(不以 __
开头),它会为这些方法添加日志记录功能。
继承与元类结合
class Character(metaclass=CharacterMeta):
def __init__(self, name):
self.name = name
class Warrior(Character):
def attack(self):
print(f"{self.name} the Warrior is attacking!")
class Mage(Character):
def cast_spell(self):
print(f"{self.name} the Mage is casting a spell!")
这里 Warrior
和 Mage
类继承自 Character
类,由于 Character
使用了 CharacterMeta
元类,所以 Warrior
和 Mage
的非特殊方法都会自动被添加日志记录功能。
多态增强可复用性和可维护性
在游戏框架中,我们可能有一个函数来处理角色的各种行为,例如:
def perform_action(character):
if hasattr(character, 'attack'):
character.attack()
elif hasattr(character,'cast_spell'):
character.cast_spell()
warrior = Warrior("Aragorn")
mage = Mage("Gandalf")
perform_action(warrior)
perform_action(mage)
多态在这里发挥了作用,perform_action
函数可以接受任何继承自 Character
的类的实例,而不需要关心具体是哪个子类。如果后续需要添加新的角色类型,只需要继承 Character
类并实现相应的方法,perform_action
函数无需修改就可以处理新的角色类型,增强了代码的可复用性。同时,如果需要修改日志记录的行为或者其他通用功能,只需要在元类中进行修改,所有继承自 Character
的子类都会自动受到影响,增强了代码的可维护性。