非静态/非全局变量被两个对象共享?原因排查求助
问题根源:可变对象的引用共享
看起来你碰到的问题核心是Python中可变对象的引用传递特性——你把Pop实例本身传给了Varient类,如果Varient的初始化方法直接引用了Pop实例里的w列表(而不是创建独立副本),那所有Varient实例都会共享同一个列表对象。
为什么会这样?因为在Python里,列表、字典这类可变对象作为参数传递时,传递的是对象的引用,而不是整个对象的副本。打个比方,就像好几个人拿着同一把钥匙开同一扇门,不管谁拧钥匙,门的状态都会变。
假设你的Varient类是这么写的:
class Varient: def __init__(self, pop_obj): self.w = pop_obj.w # 直接引用Pop实例的w列表
那所有通过Varient(self)创建的实例,它们的w属性都会指向同一个列表——也就是Pop实例里的self.w。这就导致你修改任何一个Varient的w元素时,其他Varient的w看起来也跟着变了,本质上它们本来就是同一个列表。
解决方法
方法1:在Varient初始化时创建列表副本
让每个Varient实例拥有独立的w列表,最简单的方式是在Varient的__init__里复制传入的列表:
class Varient: def __init__(self, pop_obj): # 用copy()方法创建副本,或者用切片pop_obj.w[:] self.w = pop_obj.w.copy()
如果是多维列表,需要用copy.deepcopy()来递归复制,但你的例子里是一维列表,copy()或者切片就足够了。
方法2:在Pop的populate方法中传递副本
另一种思路是在创建Varient时,直接传递w的副本而不是Pop实例本身(如果Varient不需要Pop的其他属性的话):
class Pop: def __init__(self): self.n = 2 self.w = [1.0]*12 # 简化写法,和你原来的列表等价 self.w_min = [0]*12 self.w_max = [1]*12 self.varients = [] # 记得初始化这个列表,避免报错 def populate(self, __run): for i in range(self.n): # 传递w的副本给Varient self.varients.append(Varient(self.w.copy())) class Varient: def __init__(self, w_list): self.w = w_list
额外提醒
你的Pop类里的self.varients没有在__init__中初始化,第一次调用populate时可能会抛出AttributeError,记得在Pop的__init__里加上self.varients = []哦。
内容的提问来源于stack exchange,提问作者BRobs
相关产品推荐
相关产品推荐

