【发布时间】:2012-11-09 01:58:36
【问题描述】:
对 python 很陌生,对 python 类很陌生。问题有点牵涉。非常感谢您的耐心:
我有一个班级“明星”。很简单。属性 x、v 和质量。另一个类 Galaxy 有一个属性“stars”,它只是一个星对象列表:
class Galaxy:
numstars=0.
stars=[]
def __init__(self,numin,xes,vees,masses):
self.numstars=numin
for n in range(numin):
self.stars.append(Star(xes[n],vees[n],masses[n]))
Galaxy 还有一个名为 time_stepper 的属性函数。可以说 time_stepper 只是更新“stars”的所有元素,然后返回“stars”:
def time_stepper(self,dt):
self.velstep(dt)
self.xstep(dt)
self.velstep(dt)
return(self.stars)
现在,我正在尝试驱动这个东西并将“stars”的各种更新存储在一个名为“history”的列表中:
gal=Galaxy(#stuff#)
history=[]
for n in range(100):
history.append(gal.time_stepper(.1))
最后,我的问题:在这个循环的每次迭代中,新元素“星”被添加到“历史”中,但是......这里是...... 所有以前的历史元素都是重写并赋予与历史的最新元素相同的值! 那么发生了什么?我遇到了一些我以前不理解的关于 python 列表的事情,但我想我终于把它搞定了。显然不是。感谢您的帮助。
附录: 感谢大家的帮助。没想到会有这么多有用的回复,尤其是这么快。我的问题是我假设这两段代码本质上是相同的。第一:
>>> a=[]
>>> b=[1,2,3]
>>> a.append(b)
>>> b=[4,5,6]
>>> a.append(b)
>>> a
[[1, 2, 3], [4, 5, 6]]
第二:
>>> a=[]
>>> b=[1,2,3]
>>> a.append(b)
>>> b[:]=(4,5,6)
>>> b
[4, 5, 6]
>>> a.append(b)
>>> a
[[4, 5, 6], [4, 5, 6]]
哎呀!他们不是。所以在代码 1 中,我猜,b 被“重新指向”到一个全新的内存位置,而 a[0] 继续指向旧的 b。在第二个中,b 处的内存被“编辑”并且 a[0] 仍然指向该位置。追加后, a[1] 也指向该位置。我现在有吗?
我对 python 还很陌生,并且仍在研究“pythonic”哲学。但对我来说,直接重新分配指针,但以更复杂的方式完成“深拷贝”与我通常想要做的事情的方式有点倒退。任何人都可以启发我吗?再次感谢。
【问题讨论】:
-
为什么
numstars和stars是类变量而不是实例变量? (而且,如果您确实有充分的理由,为什么要立即将numstars类替换为__init__函数中的实例numstars?) -
没有看到
Star中更新功能的代码,除了copy.deepcopy之外我很难推荐任何东西 -
Bob,你在最后一行代码中有语法错误。
-
@abarnet:你的问题的答案是我不知道我在做什么! :)
-
@inspectorG4dget: copy.deepcopy 显然是我需要的。谢谢。