首页 > 解决方案 > Python 3 - 避免实例共享或覆盖属性

问题描述

首先,我使用了 Numpy 的数组创建函数'full'(这样的数组是 Graph 类的一个属性),整个数组都有 Vertex 类的实例,每个 Vertex 都有一个坐标属性,名为 'coordsXY'(这是一个列表,其中索引 0 存储 X 位置,索引 1 存储 Y 位置)。

import numpy as np

class Vertex:

   def __init__(self):
       self.coordsXY = [0, 0]

class Graph:

   def __init__(self):
       self.vArray = np.full((8, 8), fill_value=Vertex(), dtype=np.object_)

       for i in range(0, 8):
           print(" ")
           for j in range(0, 8):
               self.vArray[i][j].coordsXY[0] = i
               self.vArray[i][j].coordsXY[1] = j

               print(self.vArray[i][j].coordsXY, end=" ")

       for m in range(0, 8):
           print(" ")
           for n in range(0, 8):
               print(self.vArray[m][n].coordsXY, end=" ")

在前 2 个 FOR 循环中一切正常:

[0, 0] [0, 1] [0, 2] [0, 3] [0, 4] [0, 5] [0, 6] [0, 7]  
[1, 0] [1, 1] [1, 2] [1, 3] [1, 4] [1, 5] [1, 6] [1, 7]  
[2, 0] [2, 1] [2, 2] [2, 3] [2, 4] [2, 5] [2, 6] [2, 7]  
[3, 0] [3, 1] [3, 2] [3, 3] [3, 4] [3, 5] [3, 6] [3, 7]  
[4, 0] [4, 1] [4, 2] [4, 3] [4, 4] [4, 5] [4, 6] [4, 7]  
[5, 0] [5, 1] [5, 2] [5, 3] [5, 4] [5, 5] [5, 6] [5, 7]  
[6, 0] [6, 1] [6, 2] [6, 3] [6, 4] [6, 5] [6, 6] [6, 7]  
[7, 0] [7, 1] [7, 2] [7, 3] [7, 4] [7, 5] [7, 6] [7, 7]

但在第二个 2 FOR 循环中:

[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]
[7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7] [7, 7]

每个 Vertex 实例的 coordsXY 属性立即被数组的最后一个 Vertex 的属性值覆盖;我能做些什么来阻止它这样做?

标签: pythonpython-3.xnumpy

解决方案


试试这个:(未测试):

class Vertex:

   def __init__(self, i, j):
       self.coordsXY = [i,j]
   def __repr__(self):
       return str(self.coordsXY)

class Graph:

   def __init__(self):
       self.vArray = np.empty((8,8), dtype=object)

       for i in range(0, 8):
           for j in range(0, 8):
               self.vArray[i,j] = Vertex(i,j)

print(Graph())

这将为数组的每个插槽创建一个新Vertex对象。既然Vertexrepr,显示器应该很好。

等价的列表

graph = []
for i in range(8):
    row = []
    for j in range(8):
         row.append(Vertex(i,j))
    graph.append(row)

print(graph)
print(np.array(graph))

full相当于[[Vertex(0,0)]*8]*8


推荐阅读