Python二维对象网格属性异常:二次打印值被覆盖问题求助
二维网格对象属性被覆盖问题解析
问题描述
通过嵌套循环创建由cell对象组成的二维网格,每个cell实例化后立即打印属性值显示正常,但退出循环后再次遍历打印时,发现self.ylo、self.path被最后一个cell的属性覆盖,self.xlo却未变化。两次遍历逻辑完全一致,为何结果不同?
复现代码
mps = ['xxxxxx', 'xoooox', 'xoxxox', 'xoooox', 'xxxxxx'] ROWS = len(mps) # equals 5 COLS = len(mps[0]) # equals 6 SCRW = 600 SCRH = 300 CELW = int(SCRW/COLS) CELH = int(SCRH/ROWS) class cell(): def __init__(self, row, col, path): self.row = row self.col = col self.path = path self.xlo = int(col*CELW) self.ylo = int(row*CELH) return row_blank = ['']*COLS grid = [row_blank]*ROWS path_list = [] for r in range(ROWS): for c in range(COLS): is_path = (mps[r][c]=='o') grid[r][c] = cell(r,c, is_path) print(f'cell {r},{c} position {grid[r][c].xlo},{grid[r][c].ylo} and path {grid[r][c].path}') print("\n==============重新打印检查!") for r in range(ROWS): for c in range(COLS): print(f'cell {r},{c} position {grid[r][c].xlo},{grid[r][c].ylo} and path {grid[r][c].path}') exit()
打印结果
cell 0,0 position 0,0 and path False cell 0,1 position 100,0 and path False cell 0,2 position 200,0 and path False cell 0,3 position 300,0 and path False cell 0,4 position 400,0 and path False cell 0,5 position 500,0 and path False cell 1,0 position 0,60 and path False cell 1,1 position 100,60 and path True cell 1,2 position 200,60 and path True cell 1,3 position 300,60 and path True cell 1,4 position 400,60 and path True cell 1,5 position 500,60 and path False cell 2,0 position 0,120 and path False cell 2,1 position 100,120 and path True cell 2,2 position 200,120 and path False cell 2,3 position 300,120 and path False cell 2,4 position 400,120 and path True cell 2,5 position 500,120 and path False cell 3,0 position 0,180 and path False cell 3,1 position 100,180 and path True cell 3,2 position 200,180 and path True cell 3,3 position 300,180 and path True cell 3,4 position 400,180 and path True cell 3,5 position 500,180 and path False cell 4,0 position 0,240 and path False cell 4,1 position 100,240 and path False cell 4,2 position 200,240 and path False cell 4,3 position 300,240 and path False cell 4,4 position 400,240 and path False cell 4,5 position 500,240 and path False ==============重新打印检查! cell 0,0 position 0,240 and path False cell 0,1 position 100,240 and path False cell 0,2 position 200,240 and path False cell 0,3 position 300,240 and path False cell 0,4 position 400,240 and path False cell 0,5 position 500,240 and path False cell 1,0 position 0,240 and path False cell 1,1 position 100,240 and path False cell 1,2 position 200,240 and path False cell 1,3 position 300,240 and path False cell 1,4 position 400,240 and path False cell 1,5 position 500,240 and path False cell 2,0 position 0,240 and path False 进程以退出码0结束。
原因分析
问题出在网格初始化的这两行代码:
row_blank = ['']*COLS grid = [row_blank]*ROWS
Python中,列表乘法[x]*n不会创建n个独立的x副本,而是创建n个指向同一对象的引用。也就是说,grid的每一行其实都是同一个row_blank列表。
循环赋值时,grid[r][c] = cell(...)看似在给不同行的位置赋值,实际是反复修改同一个列表的第c个元素。当循环到最后一行(r=4)时,所有位置的元素都被最后一行的cell对象覆盖,因此重新打印时,所有行的内容都变成了最后一行的cell属性。
至于self.xlo未被覆盖,是因为每个cell的xlo由列索引计算,最后一行每个位置的列索引和前面行对应位置的列索引一致,所以xlo值看起来没变化,本质上还是同一个cell对象的属性。
修复方案
将网格初始化改为创建独立的行列表,比如使用列表推导式:
grid = [['']*COLS for _ in range(ROWS)]
这种方式会为每一行创建一个新的列表,避免了引用复用的问题,循环赋值后每行都是独立的cell对象集合。
内容的提问来源于stack exchange,提问作者Ani
相关产品推荐
相关产品推荐

