0

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

次に、ジェネレーターコードは、各セクター(現時点では100個)に75個の星を配置し、スターディクトに保ちます。

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オブジェクトを参照しています。

なぜこれが起こっているのか分かりません。誰かがこれに光を当てることができますか?

4

1 に答える 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()

現在のコードでは、をstardict介してアクセスしようとするとself.stardict、Pythonは最初stardictインスタンスstardictを検索しますが、そこに属性が見つからない場合は、クラスを検索します。stardictクラスで見つけたので、それを使用します。しかし、これは、すべてのインスタンスが同じものを見つけることを意味しますstardict(同じクラスのすべてのインスタンスであるため)-それらの1つとstardict他のすべてのインスタンスへの更新は(光速よりも速い!)*を認識します。

*これは物理法則を損なうものではないことに注意してください。それらは同じオブジェクトであるため、情報が移動する距離はありません...

于 2013-03-19T00:41:30.813 に答える