Python开发D&D角色卡工具时如何动态生成对应属性修饰符变量名
问题修正与实现方案
你当前编写的calculateMod存在两个基础问题:
for n in range(0)的循环体永远不会执行,range(0)是空可迭代对象- 仅传入属性值(比如
character.strength本质是整数、浮点数这类纯值)时,函数无法获知该值对应的属性名是strength,自然没法生成对应命名的修饰符变量——纯数值本身不携带来源属性的名称信息。
下面是可落地的实现方式,按推荐优先级排序:
方案1:在角色类内部实现修饰符逻辑(最推荐,可维护性最高)
不要写游离在类外的计算函数,直接把修饰符作为类的内置能力,既不需要额外传参,也不会出现命名混乱、变量污染的问题:
import math class DnDCharacter: def __init__(self, strength, dexterity, constitution, intelligence, wisdom, charisma): self.strength = strength self.dexterity = dexterity self.constitution = constitution self.intelligence = intelligence self.wisdom = wisdom self.charisma = charisma # 通用获取修饰符的方法 def get_mod(self, attr_name: str): attr_val = getattr(self, attr_name) return math.floor((attr_val - 10) / 2) # 动态匹配xxxMod形式的属性访问,不需要逐个写property def __getattr__(self, name): if name.endswith("Mod"): base_attr = name.removesuffix("Mod") if hasattr(self, base_attr): return math.floor((getattr(self, base_attr) - 10) / 2) raise AttributeError(f"角色对象不存在属性 {name}")
调用示例:
# 初始化一个力量16、敏捷12、感知8的角色 new_char = DnDCharacter( strength=16, dexterity=12, constitution=14, intelligence=10, wisdom=8, charisma=13 ) print(new_char.strengthMod) # 输出3 print(new_char.dexterityMod) # 输出1 print(new_char.get_mod("wisdom")) # 输出-1
方案2:保留独立函数,传入对象实例和属性名
如果一定要把计算逻辑抽成独立函数,必须同时传入角色实例和属性名字符串,函数会直接给实例挂载对应命名的修饰符属性:
import math def calculateMod(char_instance, attr_name: str): attr_val = getattr(char_instance, attr_name) mod_val = math.floor((attr_val - 10) / 2) setattr(char_instance, f"{attr_name}Mod", mod_val) return mod_val # 调用示例 class Character: def __init__(self, strength): self.strength = strength test_char = Character(strength=18) calculateMod(test_char, "strength") print(test_char.strengthMod) # 输出4
不推荐方案:动态修改全局变量
如果非要在全局作用域直接生成strengthMod这类独立变量,可以通过globals()字典动态赋值,但这种方式会严重污染全局命名空间,极易出现命名冲突、调试困难的问题,正式项目不要用:
import math # 反面示例,仅做原理展示 def calculateMod(attr_name: str, attr_val: int): mod_val = math.floor((attr_val - 10)/2) globals()[f"{attr_name}Mod"] = mod_val calculateMod("strength", 16) print(strengthMod) # 输出3
内容的提问来源于stack exchange,提问作者DamienJ
相关产品推荐
相关产品推荐

