类的所有实例与Python 3.2中的属性具有相同的dict [英] All instances of a class have the same dict as an attribute in Python 3.2

查看:114
本文介绍了类的所有实例与Python 3.2中的属性具有相同的dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是通过拥有一个Sector对象来处理的,其定义如下:

  class Sector:
x = 0 #Position的扇区。任何对象的星系(绝对)位置是其行内位置
y = 0 #plus银河位置偏移乘以扇区大小。
stardict = dict()

然后,生成器代码填充每个扇区(其中100个在这个时刻)与75星,保持stardict。

  thesector = Sector()

size = size / 2

#生成星星
(范围内的t):
#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))

如果math.floor((t / stars)* 100)==(t /星星)* 100:print(生成星星+ str((t / stars)* 100)+完成%

但是,尝试实际运行该程序时会出现一些奇怪的错误,并且使用调试器打开它会显示为什么:每个扇区的stardict属性是相同的,它们各自包含完全相同的星重复,他们有相同的内存地址)。据我所知,每个Sector.stardict实际上都是引用相同的dict对象。



我不知道为什么会发生这种情况。任何人都可以这么说吗?

解决方案

他们正在引用同一个对象。这是一个非常常见的问题。如果你希望他们每个都有自己的 dict ,你需要在 __ init __ 方法中创建它。 p>

  class Sector:
x = 0#行业的位置。任何对象的星系(绝对)位置是其行内位置
y = 0 #plus银河位置偏移乘以扇区大小。
def __init __(self):
self.stardict = dict()

当你的代码目前站立时,当您尝试通过 self.stardict 访问 stardict 时,python首先查找 stardict 实例上,但是当它没有找到 stardict 属性时,它看起来。它在类上找到 stardict ,所以它使用它。但是,这意味着所有实例都找到相同的 stardict (因为它们是同一个类的所有实例) - 更新到其中一个 stardict 所有其他人都会知道(比光速快!)*。



*请注意,这并不会消除任何物理学规律。由于他们是同一个对象,所以没有距离的信息旅行...


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?

解决方案

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 ...

这篇关于类的所有实例与Python 3.2中的属性具有相同的dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆