Python 3.2中类的所有实例共享同一个字典属性
我正在用Python写一个太空贸易游戏,我决定把地图分成更小的块,这样可以减少每次在屏幕上绘制时需要考虑的对象数量。
这个问题是通过一个叫做Sector的对象来解决的,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()
然后,生成器代码会给每个区域(目前有100个)填充75颗星星,这些星星保存在一个叫做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实际上都在引用同一个字典对象。
我不知道为什么会这样。有没有人能帮我解释一下?
1 个回答
5
他们指的是同一个对象。这是一个非常常见的误区。如果你想让它们各自拥有自己的 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()
根据你现在的代码,当你通过 self.stardict
访问 stardict
时,Python 首先会在这个对象的实例中查找 stardict
,如果找不到,就会去类里面查找。它在类中找到了 stardict
,所以就使用这个了。但是,这意味着所有的实例都找到了同一个 stardict
(因为它们都是同一个类的实例)——如果其中一个实例更新了它的 stardict
,其他的实例也会立刻知道(比光速还快!)*
*注意,这并不违反任何物理定律。因为它们是同一个对象,所以信息没有距离可言……