Python 遍历对象实例列表按条件筛选修改及字符串转对象实例问题
报错原因与代码修正
「List indices must be ints, not objects」的触发根源
- Python 的
for i in 列表遍历语法中,循环变量i拿到的是列表存储的实际元素,而非整数索引。传入的列表存储的是玩家实例对象,因此循环中i本身就是玩家对象,原代码继续用self.playerlist[i]做索引取值时,就会因为传入非整数的对象当索引发送报错。 - 原代码存在两处逻辑偏差:
- 调用
distance()时只传入了玩家的xpos、ypos,漏了距离计算的另一端点(即运行该方法的self实例的坐标),计算结果不符合预期。 caughtBall = True的赋值语句写在if判断块外部,会导致所有被遍历的玩家无论是否满足接球条件,属性都会被修改,和预期逻辑不符。
- 调用
符合需求的正确实现
def distToPlayers(self, player_list): self.playerlist = player_list returnls = [] for player in self.playerlist: # 计算玩家与当前self实例的距离,需传入双方坐标 current_dist = distance(player.xpos, player.ypos, self.xpos, self.ypos) if current_dist <= player.catchRadius: player.caughtBall = True returnls.append(player) return returnls
- 注意不要将参数名命名为
list,该名称是Python内置的列表类型关键字,自定义参数重命名为player_list可避免覆盖原生功能。 - 若遍历过程中需要同步获取元素的整数位置序号,可使用
enumerate()实现,无需手动通过整数索引取值:for index, player in enumerate(self.playerlist): print(f"列表第{index}位的玩家坐标:{player.xpos}, {player.ypos}")
字符串转对应对象实例的实现方案
尝试用obj()、object()将字符串转为对象实例失败,是因为这类内置方法本身不支持字符串到实例的映射,可通过以下两种方式实现:
- 方案1(推荐):维护独立的名称-实例映射字典,可控性最强
# 完成所有玩家实例初始化后,手动建立名称与实例的对应关系 player_instance_map = { "receiver1": receiver1, "defback1": defback1, } def distToPlayers(self, player_name_list): self.playerlist = player_name_list returnls = [] for player_name in player_name_list: # 从映射字典中取出对应玩家实例 current_player = player_instance_map[player_name] current_dist = distance(current_player.xpos, current_player.ypos, self.xpos, self.ypos) if current_dist <= current_player.catchRadius: current_player.caughtBall = True returnls.append(current_player) return returnls - 方案2:通过内置的
globals()方法从全局作用域按字符串名取实例该方式可控性较弱,若传入的字符串不存在对应全局变量会触发
KeyError,仅适合快速调试场景,生产环境优先用映射字典方案。def distToPlayers(self, player_name_list): self.playerlist = player_name_list returnls = [] for player_name in player_name_list: # 从全局变量域中按字符串名匹配对应实例 current_player = globals()[player_name] current_dist = distance(current_player.xpos, current_player.ypos, self.xpos, self.ypos) if current_dist <= current_player.catchRadius: current_player.caughtBall = True returnls.append(current_player) return returnls
内容的提问来源于stack exchange,提问作者VlonaldTrutin
相关产品推荐
相关产品推荐

