如何在Python中对Player类属性排序、随机化并直接修改属性本身?
针对Player类属性的修改需求与解决方案
需求说明
需要对Player类实例的6个核心属性执行两个操作:
- 找到其中数值最小的属性,将其值加1
- 随机选取一个属性,将其值加1
Player类的相关属性定义如下:
class Player: def __init__(self, name): self.name = name self.level = 1 self.experience = 0 self.gold = 500000 self.wielded_weapon = short_sword self.armor = padded_armor self.shield = no_shield self.boots = leather_boots # 重点操作的6个属性 self.strength = 15 self.dexterity = 14 self.constitution = 13 self.intelligence = 12 self.wisdom = 8 self.charisma = 10
之前的问题
你之前用字典存储属性值的方式,本质是把属性值复制到了字典里,修改字典内的数值只是修改了副本,完全不会影响Player实例本身的属性:
# 错误的字典定义:存的是属性值的副本 ability_dict = {1: self.strength, 2: self.dexterity, 3: self.constitution, 4: self.intelligence, 5: self.wisdom, 6: self.charisma} # 这些操作只改字典,和实例属性无关 min_value = min(ability_dict.values()) min_value += 1 rndm_attribute = random.choice(list(ability_dict.values())) rndm_attribute +=1 minimum_key = min(ability_dict, key=ability_dict.get) ability_dict[minimum_key] += 1
解决方案
核心是直接操作实例的属性本身,而不是操作值的副本。可以通过存储属性名称字符串,结合Python内置的getattr()和setattr()方法实现:
1. 先定义目标属性列表
把要操作的6个属性名称存成列表,方便后续调用:
ability_names = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"]
2. 找到最小值属性并加1
遍历属性名称,获取对应的值,找到最小值对应的属性名,再直接修改实例属性:
import random # 找出数值最小的属性名称 min_ability = min(ability_names, key=lambda attr: getattr(self, attr)) # 给这个属性加1 setattr(self, min_ability, getattr(self, min_ability) + 1)
3. 随机选取属性并加1
用random.choice()随机选一个属性名称,再修改其值:
random_ability = random.choice(ability_names) setattr(self, random_ability, getattr(self, random_ability) + 1)
完整封装示例
可以把这两个操作做成Player类的一个方法,方便调用:
class Player: def __init__(self, name): self.name = name self.level = 1 self.experience = 0 self.gold = 500000 self.wielded_weapon = "short_sword" self.armor = "padded_armor" self.shield = "no_shield" self.boots = "leather_boots" self.strength = 15 self.dexterity = 14 self.constitution = 13 self.intelligence = 12 self.wisdom = 8 self.charisma = 10 def boost_abilities(self): import random ability_names = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"] # 给最小值属性加1 min_ability = min(ability_names, key=lambda attr: getattr(self, attr)) setattr(self, min_ability, getattr(self, min_ability) + 1) # 随机选属性加1 random_ability = random.choice(ability_names) setattr(self, random_ability, getattr(self, random_ability) + 1)
为什么这样有效?
直白来说,getattr(obj, attr_name)是直接拿对象的属性值,setattr(obj, attr_name, new_value)是直接给对象的属性赋值。存储属性名称而非属性值,就能绕开“副本”问题,直接操作实例本身的属性,修改自然会生效。
内容的提问来源于stack exchange,提问作者misfit138
相关产品推荐
相关产品推荐

