2013-05-15 118 views
2

我對Python和一般編程頗爲陌生。Python:基於變量的名稱實例

我正在做一個基於終端的遊戲作爲一個實踐項目。遊戲將會有一系列的房間和怪物。我的計劃是製作這些課程的怪物和房間實例。我在整個遊戲中創建了其中的幾個,其中許多是基於玩家操作而實時創建的。

當創建新的怪物和房間時,我現在堅持事先知道他們的名字。像這樣:

class Monster(object): 
    pass 

Monster1 = Monster(something) 

必須知道實例名稱預運行時似乎是一個笨拙的解決方案。我認爲讓變量跟蹤怪物的數量會更容易,然後動態創建實例名稱。因此,創建將automaticallt第一妖實例是Monster1,接下來的將是Monster2等

事情是這樣的:

class Monster(object): 
    pass 

monster_id = 0 

def createMonster(monster_id) 
monster_instance = "Monster" + str(monster_id) 
monster_id += 1 
# The following is where i'm stuck. Basically I want to have the instance name be equal to the content of monster_instance 
(monster_instance) = Monster() 

所以問題是:我怎麼能不知道創建一個類的實例實例運行前的名稱?

我也想知道如果我很難讓這個工作,因爲我做了一些愚蠢的事情,這是一個更聰明/優雅的做法。所有的幫助和投入在任何情況下都受到讚賞。

回答

7

這是一個來自新手的常見問題,你是對的,有一個「更聰明/優雅的做法」。您可以使用像一本字典的數據結構來保存你的實例:

monsters = {} 
monsters['Monster1'] = Monster() 
monsters['Monster2'] = Monster() 

由於密鑰的字典是字符串,也沒有在運行時將它們定義問題,只要你喜歡:

monster_name = "Monster" + str(monster_id) 
monster_id += 1 
monsters[monster_name] = Monster() 
+0

感謝您的反饋。這正是我期待的!謝謝:-) – Splurk

0

所以問題是:如何知道預運行時實例的名稱而不知道 的實例?

你不知道。你很困惑。

您只能在運行時創建實例,並且不希望將有關該對象的任何信息編碼爲變量名,因爲程序不會與變量名進行交互。

您使用數據結構來跟蹤您的對象。如果他們需要一個唯一的ID,最好的解決方案是在對象創建時分配一個UUID。

+0

有可能在Python創建DINAMIC類[使用的元類(http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python) –

+0

@SaulloCastro(a)中可以在不使用元類的情況下創建動態類(b)問題和答案都不討論動態類,所以我不明白你的評論的重點。 – Marcin

+0

我認爲這個問題可以通過動態類來解決。當我讀到你的答案時,我不同意的一點是你不能在不知道實例運行時的名稱的情況下創建類的實例。但現在我相信我明白了你的觀點......實例的名稱必須事先知道,我明白「類的名稱」... –

5

我很確定你並不真正想做你正在問怎麼做。

您應該使用數據結構來保存對象,而不是創建動態名稱(以後無法使用,因爲您不知道名稱)。例如,list可以很容易地通過一個整數索引,所以你monster1變量可以成爲monsters[1]

# create the list of monsters 
monsters = [Monster(1), Monster(2), Monster(3)] # or whatever parameters 

# then later, use it 
monster[1].eat_player() 

或者,而不是提前設置整個列表的時間和使用顯式的索引,你可以讓列表動態並遍歷它:

# setup 
monsters = [] # empty list 

# later, dynamically add monsters 
monster_spawn_timer -= 1 
if monster_spawn_timer < 0: 
    monster_spawn_timer += MONSTER_SPAWN_INTERVAL 
    monsters.append(Monster()) 

# and at some other point in your main loop, you can iterate over the monsters: 
for m in monsters: 
    m.do_stuff() 
+0

感謝您的反饋!我最終使用了Richie的解決方案,但我也絕對可以看到這種方法的優點。我很可能最終也會使用其中的一些。謝謝! – Splurk

1

你有三個選擇:

  1. 使用evaleval(monster_instance + ' = Monster()')。 eval基本上執行一個字符串。請注意,正如RichieHindle在評論中所說,eval不是理想的解決方案。這可能是一個選項,但這並不意味着它是建議的。

  2. 使用數組/列表:monsters.append(Monster())。使用monsters = []進行初始化。

  3. 使用字典:monsters[monster_instance: Monster()]monsters.update({monster_instance: Monster()})。使用monsters = dict()進行初始化。

+3

請不要鼓勵新手使用'eval'或'exec'。這很少是正確的答案。 – RichieHindle

+0

@RichieHindle:謝謝你的建議。我編輯了這篇文章。 – refi64

+1

我最初研究這個時發現eval,但幸運的是大多數帖子都說現在我應該遠離它。但感謝輸入:-) – Splurk