Python实现字符串转类对象问题求解(Discord机器人开发场景)
解决方案
第一步:新增敌人实例注册表,自动注册所有创建的敌人
你不需要手动编写大量if判断,只要新增一个字典作为「字符串-敌人实例」的映射容器,在敌人实例初始化时自动注册进去即可,示例中我们同时支持用户输入敌人类型(比如!attack skeleton)和敌人全名(比如!attack Randy Bones)两种匹配规则:
首先定义全局注册表:
# 全局敌人注册表,key为用户可输入的匹配字符串,value为对应敌人实例 enemy_registry = {} # 你原本的npc_info变量可以保留,不影响原有逻辑 npc_info = []
修改敌人类的__init__方法,自动完成注册:
class EnemyCreator: type = 'enemy' def __init__(self, name, enemy_type, health, ap): self.name = name self.enemy_type = enemy_type self.health = health self.ap = ap info = (name + ', ' + str(health) + ', ' + str(ap)) npc_info.append(info) # 自动注册到注册表,统一转小写避免大小写匹配问题 enemy_registry[name.lower()] = self enemy_registry[enemy_type.lower()] = self
你原有创建敌人实例的代码不需要做任何修改,实例创建时会自动进入注册表:
skeleton = EnemyCreator('Randy Bones', 'skeleton', 100, 2)
第二步:优化原有逻辑,补全校验流程
首先修正你原有attack函数的判断顺序bug:原逻辑先判断敌人血量、再判断玩家血量,会导致玩家被反击打死时无法正常返回死亡提示,调整后代码如下:
def attack(enemy): enemy.health = enemy.health - playerChar.ap # 先判断敌人是否被击败 if enemy.health <= 0: return enemy.name + ' has been defeated!' # 敌人未死亡则触发反击 playerChar.health = playerChar.health - enemy.ap # 再判断玩家是否被击败 if playerChar.health <= 0: return 'You died idiot.' # 双方都存活时返回正常战斗信息 return ('You attacked ' + enemy.name + '. ' + str(enemy.health) + ' life remaining. \n' + enemy.name + ' attacks back! You take ' + str(enemy.ap) + ' damage. You have ' + str(playerChar.health) + ' remaining!')
修改消息监听逻辑,先对用户输入做匹配校验,再调用攻击函数:
async def on_message(message): print(message.content) if message.author != client.user: if 'test' in message.content.lower(): print(npc_info) if '!attack' in message.content.lower(): # 截取用户输入的敌人信息,去除前后空格后转小写匹配 input_enemy = message.content[8:].strip().lower() # 从注册表查询对应敌人实例 target_enemy = enemy_registry.get(input_enemy) if not target_enemy: # 未匹配到敌人时返回提示 await message.channel.send("未找到对应敌人,请检查输入的名称是否正确") return # 匹配成功则传入实例调用攻击函数 await message.channel.send(attack(target_enemy))
扩展说明
- 如果存在同类型/同名称的多个敌人,可以将注册表的value修改为实例列表,匹配到多个结果时提示用户选择攻击目标即可
- 后续新增任何敌人实例,都会自动进入注册表完成匹配支持,不需要额外编写判断逻辑
内容的提问来源于stack exchange,提问作者AThomspon
相关产品推荐
相关产品推荐

