Python 对象属性更改值

python object attribute changing values

提问人:Ani 提问时间:10/25/2023 更新时间:10/25/2023 访问量:27

问:

我正在嵌套循环中创建单元格对象的网格(二维列表)。在实例化每个单元格后,我立即打印了其属性的值。退出循环后,我再次遍历单元格并重新打印其属性值。某些值似乎没有变化 (self.xlo),而某些属性似乎已被最后一个单元格的属性值(self.ylo、self.path)替换。 这两个 print 语句是相同的,并且遵循相同的嵌套循环。为什么结果不同?

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==============Re-Printing to check!")
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()

感谢您的指导 - 我似乎在 python OOP 对象上犯了一个非常根本的错误。打印语句的结果如下 - 第一组正确,重新打印有变化。

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

==============Re-Printing to check!
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

Process ended with exit code 0.

>
Python OOP 属性

评论


答:

1赞 matszwecja 10/25/2023 #1

问题出在这两行:

row_blank = ['']*COLS
grid = [row_blank]*ROWS

以这种方式创建列表时,最终会得到包含对同一行对象的多个引用的“网格”。

第一次打印具有“正确”值,因为您可以边走边打印。您分配初始值,打印它们,在下一次迭代中,您分配新值并打印它们,依此类推。如果您分离赋值并打印值,您也会在那里看到问题。

您可以使用以下代码进行检查:

for row in grid:
    print(id(row))

哪个输出(确切的数字无关紧要,重要的是它是相同的数字 - 这意味着相同的对象):

1714813861696
1714813861696
1714813861696
1714813861696
1714813861696

相反,你应该像这样初始化你的网格,这样可以确保每一行都是一个唯一的对象。

grid = [['' for _ in range(COLS)] for _ in range(ROWS)]