我不确定这里发生了什么。但是我列表中的元素不断变化。
table._row_gen
是一个生成器实例,它为我的表创建行。来源是here。
返回dict
;我也可以直接从dict
获取table._row_gen.stats
。
def test_append(self):
start_stats = {'step':250,'offset':13,'inc':113,'danger':0,'input':None}
gen = StatGenerator(start_stats)
table = PathTable(gen)
stats_list = []
for i in xrange(50):
stats_list.append(table._row_gen.stats)
print stats_list[i]
table._row_gen.next()
assert stats_list[0]['step'] == 250
这应该构建一个到stats_list
的行列表。
print
正常工作并显示正确的输出:
{'danger': 0, 'input': None, 'step': 250, 'inc': 113, 'offset': 13}
{'enc': False, 'danger': 113, 'rnd': 216, 'step': 252, 'limit': 55552, 'offset': 13, 'inpu
{'enc': False, 'danger': 226, 'rnd': 163, 'step': 254, 'limit': 41984, 'offset': 13, 'inpu
{'enc': False, 'danger': 339, 'rnd': 151, 'step': 0, 'limit': 38912, 'offset': 26, 'input'
{'enc': False, 'danger': 452, 'rnd': 212, 'step': 2, 'limit': 54528, 'offset': 26, 'input'
{'enc': False, 'danger': 565, 'rnd': 64, 'step': 4, 'limit': 16640, 'offset': 26, 'input'
但是列表格式不正确,assert
失败了:
> assert stats_list[0]['step'] == 250
E assert 94 == 250
test_int_path_table.py:47: AssertionError
循环后:
print stats_list[0]
{'enc': True, 'danger': 5650, 'rnd': 6, 'step': 94, 'limit': 1792, 'offset': 26, 'input':
94应该是最后一行。然而,所有行报告都是相同的:
print stats_list[0] is stats_list[48]
True
我真的不明白为什么会这样,我希望列表正确(如print
输出)。
答案 0 :(得分:1)
简单的解决方案是制作副本。为此,你可以做到
def test_append(self):
start_stats = {'step':250,'offset':13,'inc':113,'danger':0,'input':None}
gen = StatGenerator(start_stats)
table = PathTable(gen)
stats_list = []
for i in xrange(50):
stats_list.append(table._row_gen.stats.copy()) # <=== the copy call makes a new copy and solves your problem.
print stats_list[i]
table._row_gen.next()
assert stats_list[0]['step'] == 250
此外,for块末尾的next
调用是无关紧要的。它可以使用
def test_append(self):
start_stats = {'step':250,'offset':13,'inc':113,'danger':0,'input':None}
gen = StatGenerator(start_stats)
table = PathTable(gen)
stats_list = []
for i in xrange(50):
stats_list.append(next(table._row_gen).copy())
print stats_list[i]
assert stats_list[0]['step'] == 250
如果你控制了pastebin代码,stats属性应该返回一个防御性副本。
@property
def stats(self):
return self._stats.copy()
并且next
方法也应该返回防御性副本。
def next(self):
''' Generates and returns stats. '''
row = self._stats
row['step'] = self._genStepId(self._stats['step'])
row['offset'] = self._genOffset(self._stats['offset'], self._stats['step'])
row['danger'] = self._genDanger(self._stats['danger'], self.stats['inc'])
row['rnd'] = self._genRnd(self.rnlut[self._stats['step']], self._stats['offset'])
row['limit'] = self._genDangerLimit(self._stats['rnd'])
row['enc'] = self._genEnc(self._stats['danger'], self._stats['limit'])
return self.stats
如果您执行上述两个区块,则不再需要前两个区域中的副本。