Python类属性传递至外部函数后未修改的问题排查
问题:调用外部函数修改类实例属性未生效的原因及解决办法
问题现象
创建Test类包含hp和max_hp属性,调用外部函数recovery_action试图在属性未达最大值时为其加1,但调用后属性值未发生变化。
原代码
class Test: def __init__(self): self.hp = 10 self.max_hp = self.hp def recovery_action(attribute, max_attribute): if attribute == max_attribute: pass else: attribute += 1 test = Test() test.hp -= 5 print(f'test.hp - {test.hp}') recovery_action(test.hp, test.max_hp) print(f'test.hp after recovery - {test.hp}')
执行输出
test.hp - 5 test.hp after recovery - 5
问题原因
这是Python不可变类型参数传递的特性导致的:
hp是整数类型,属于不可变类型。当你把test.hp作为参数传给recovery_action时,传递的是该整数的副本(准确说是不可变对象的引用,但修改时会创建新对象,而非修改原对象)。- 函数内部对
attribute执行+=1操作,只是修改了这个局部变量的取值,和原实例的test.hp没有关联,自然不会影响原属性的值。
解决办法
方法1:传递实例和属性名称(适配多类实例)
把实例和属性名(字符串)传给函数,通过实例的属性访问直接修改原属性,这种方式可以适配其他类的实例:
class Test: def __init__(self): self.hp = 10 self.max_hp = self.hp def recovery_action(instance, attr_name, max_attr_name): attribute = getattr(instance, attr_name) max_attribute = getattr(instance, max_attr_name) if attribute != max_attribute: setattr(instance, attr_name, attribute + 1) test = Test() test.hp -= 5 print(f'test.hp - {test.hp}') recovery_action(test, 'hp', 'max_hp') print(f'test.hp after recovery - {test.hp}')
方法2:返回修改后的值,外部赋值
让函数返回修改后的属性值,在调用后手动赋值给实例属性:
class Test: def __init__(self): self.hp = 10 self.max_hp = self.hp def recovery_action(attribute, max_attribute): if attribute != max_attribute: return attribute + 1 return attribute test = Test() test.hp -= 5 print(f'test.hp - {test.hp}') test.hp = recovery_action(test.hp, test.max_hp) print(f'test.hp after recovery - {test.hp}')
方法3:将函数改为类的方法(针对该类或子类场景)
如果不需要适配完全无关的类,也可以把恢复逻辑写成类的方法:
class Test: def __init__(self): self.hp = 10 self.max_hp = self.hp def recovery_action(self): if self.hp != self.max_hp: self.hp += 1 test = Test() test.hp -= 5 print(f'test.hp - {test.hp}') test.recovery_action() print(f'test.hp after recovery - {test.hp}')
内容的提问来源于stack exchange,提问作者user20928160
相关产品推荐
相关产品推荐

