遍历对象实例变量无法修改值,如何通过中间变量更新属性?
如何通过中间变量更新类中的numpy数组实例变量?
首先定义包含两个numpy数组实例变量的类:
import numpy as np class test(object): def __init__(self): self.a=np.array((1,2)) self.b=np.array((1,2))
尝试通过遍历中间变量执行np.insert操作,发现无法更新self.a和self.b:
def indirect_method(self): arrs = [self.a, self.b] for a in arrs: a = np.insert(a,1,3) t=test() t.indirect_method() print(t.a) # 输出: array([1, 2]) print(t.b) # 输出: array([1, 2])
打印ID验证发现,执行np.insert后循环变量的ID发生变化,说明生成了新数组对象:
def indirect_method(self): arrs = [self.a,] print(id(self.a)) for a in arrs: print(id(a)) a = np.insert(a,1,3) print(id(a)) t=test() t.indirect_method() # 输出: # 4756930896 # 4756930896 # 4744668432
而直接修改实例变量则能正常生效:
def direct_method(self): self.a = np.insert(self.a,1,3) self.b = np.insert(self.b,1,3) t=test() t.direct_method() print(t.a) # 输出: array([1, 3, 2]) print(t.b) # 输出: array([1, 3, 2])
原因分析
np.insert不会就地修改原数组,而是返回一个全新的数组对象。循环中a最初是self.a的引用,但执行a = np.insert(...)后,a会指向新生成的数组,和self.a的引用关系被切断,自然无法更新原实例变量。
解决方案
方法1:遍历属性名,用setattr批量更新
适合每个变量需要不同插入位置的场景:
def update_arrays(self): # 键是实例变量名,值是对应的插入位置 attr_pos_map = {"a": 1, "b": 1} for attr_name, insert_pos in attr_pos_map.items(): # 获取当前数组 current_arr = getattr(self, attr_name) # 生成新数组 new_arr = np.insert(current_arr, insert_pos, 3) # 更新实例变量 setattr(self, attr_name, new_arr)
方法2:统一处理相同插入位置的变量
如果所有变量的插入位置一致,可以简化:
def update_arrays(self, insert_pos=1): # 列出需要更新的实例变量名 attr_names = ["a", "b"] for name in attr_names: setattr(self, name, np.insert(getattr(self, name), insert_pos, 3))
测试效果
t = test() t.update_arrays() print(t.a) # 输出: array([1, 3, 2]) print(t.b) # 输出: array([1, 3, 2])
内容的提问来源于stack exchange,提问作者Echo6
相关产品推荐
相关产品推荐

