我正在用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对象。
我不知道为什么会这样。谁能对此有所启发?
他们指的是同一个对象。这是一个非常常见的陷阱。如果希望它们每个都有自己的dict,则需要在__init__方法中创建它。
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都知道(快于光速!)*。
stardict
self.stardict
*请注意,这不会破坏任何物理定律。由于它们是同一对象,因此信息传播没有距离…