All instances of a class have the same dict as an attribute in Python 3.2

房东的猫 提交于 2019-11-28 11:49:30

问题


I'm writing a space trading game in Python, and I've decided that the map needs to be split into smaller chunks to reduce the number of objects that need to be considered for drawing on the screen at any given time.

This is handled by having a Sector object, which is defined as such:

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()

Then, the generator code populates each sector (100 of them at the moment) with 75 stars, kept in 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.")

However, there's some strange bugs when trying to actually run the program, and opening it with the debugger shows why: the stardict attribute of each sector is identical, they each contain the exact same stars (not duplicates, they have the same memory address). As far as I can tell, each Sector.stardict is actually referencing the same dict object.

I have no idea why this is happening. Can anyone shed some light on this?


回答1:


They are refering to the same object. This is a very common gotcha. If you want them to each have their own dict, you need to have it created in the __init__ method.

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()

As your code currently stands, when you try to access stardict via self.stardict, python first looks for stardict on the instance, but when it doesn't find a stardict attribute there, it looks on the class. It finds stardict on the class, so it uses that. But, this implies that all instances find the same stardict (since they all instances of the same class) -- an update to one of their stardict and all of the others will know (faster than light speed!)*.

*Note that this doesn't voilate any laws of physics. Since they are the same object, there is no distance for the information to travel ...



来源:https://stackoverflow.com/questions/15489567/all-instances-of-a-class-have-the-same-dict-as-an-attribute-in-python-3-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!