小编典典

类的所有实例与python 3.2中的属性具有相同的dict

python

我正在用Python编写一个空间交易游戏,并且我决定需要将地图分成较小的块,以减少在任何给定时间在屏幕上绘制时需要考虑的对象数量。

这通过具有一个Sector对象来处理,该对象的定义如下:

class Sector:
   x=0     #Position of the sector. The galactic (absolute) position of any object is its in-sector position
   y=0     #plus the galactic position offset times the size of a sector. 
   stardict=dict()

然后,生成器代码将75个星标填充在每个扇区中(此刻目前为100个扇区),并保留在stardict中。

thesector=Sector()

size=size/2

#Generate stars
for t in range(stars):
    #name="Star "+str(t)
    name=generate_name().capitalize()
    thesector.stardict[name]=Star( name, (random.randint(-size,size), random.randint(-size,size)), (random.randint(0,255), random.randint(0,255), random.randint(0,255)), random.randint(3,7))

    if math.floor((t/stars)*100)==(t/stars)*100: print("Generating stars: "+str((t/stars)*100)+"% done.")

但是,在尝试实际运行程序时会出现一些奇怪的错误,并且使用调试器打开它可以说明原因:每个扇区的stardict属性是相同的,它们每个都包含完全相同的星星(不是重复的,它们具有相同的内存地址)
。据我所知,每个Sector.stardict实际上都引用同一个dict对象。

我不知道为什么会这样。谁能对此有所启发?


阅读 175

收藏
2021-01-20

共1个答案

小编典典

他们指的是同一个对象。这是一个非常常见的陷阱。如果希望它们每个都有自己的dict,则需要在__init__方法中创建它。

class Sector:
   x = 0     #Position of the sector. The galactic (absolute) position of any object is its in-sector position
   y = 0     #plus the galactic position offset times the size of a sector. 
   def __init__(self):
       self.stardict = dict()

就目前的代码而言,当您尝试stardict通过进行访问时self.stardict,python首先stardict实例
上查找,但是当在 实例 中找不到stardict属性时,它将在 class
上查找。它stardict在类上找到,因此使用它。但是,这意味着所有实例都找到相同的对象stardict(因为它们所有相同类的实例)-更新它们中的一个实例以及所有其他实例stardict都知道(快于光速!)*。

*请注意,这不会破坏任何物理定律。由于它们是同一对象,因此信息传播没有距离…

2021-01-20