2011-01-27 105 views
4

我有以下代碼:Python:調用另一個類的方法的最佳方法?

class Player: 
    def __init__(self, username, trip, model): 
     self.username = username 
     self.trip = trip 
     self.hp = 100 


    #### For player moving location/room #### 
    def Move(self, dest): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

一個遊戲是被這個類外定義因此,此代碼不工作的陣列。 既然有可能成爲這一類中的許多其他功能,這將有可能使用一個遊戲陣列,我應該這樣做:

class Player: 
    def __init__(self, username, trip, model, aGame): 
     self.username = username 
     self.trip = trip 
     self.hp = 100 
     self.aGame = aGame    

    #### For player moving location/room #### 
    def Move(self, dest): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in self.aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

或者它會更好地做到這一點:

class Player: 
    def __init__(self, username, trip, model): 
     self.username = username 
     self.trip = trip 
     self.hp = 100   

    #### For player moving location/room #### 
    def Move(self, dest, aGame): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

或者我應該讓aGame成爲一個全局變量(如果是這樣,請注意這個類在不同的文件中)?

由於aGame是一個遍佈整個地方的數組,因此在每個類中都要複製它並不正確。 我可能有這個錯誤,我慢慢地學習OOP,所以謝謝你的幫助。

+3

實際上,您不會將aGame字典複製到每個類中,而是通過引用傳遞參數。 – miku 2011-01-27 03:27:38

回答

3

在我看來,第一個選項是正確的,因爲它沒有很好的理由使用全局變量。所以選擇在第二和第三之間。

決定功能是如果您打算要使用同一個Player實例來獲得多個aGame值。如果只有一個值,那麼我會將它傳遞給構造函數(您的選項2)或使用gnibbler的使其成爲類變量的想法。我可能會傾向於將它傳遞給構造函數以便於測試。

如果您希望同一個Player實例可與多個aGame值一起使用,那麼選項3可能是最簡單的方法。

0

只有第一選擇纔有效。在第二個例子中,for room in self.aGame['rooms']將產生一個錯誤,因爲無處遊戲是綁定到自己的。它會工作,如果它是for room in aGame['rooms'],但那麼你必須不必要地通過遊戲每次你打電話move()

您也可以將其設爲全局變量,但最好是讓每個玩家都擁有一個aGame實例。如果您需要更改aGame並擁有多個玩家,則應將其定義爲全局變量。

此外,只是挑剔,但aGame不是一個數組,它是一個字典。 Python語言甚至沒有數組(儘管有些擴展可以)。

+0

對不起,我忘了刪除'自我'。因爲在第二個例子中,aGame變量被傳入了方法。 – Tommo 2011-01-27 03:28:04

+0

如果我向Player類添加了一個遊戲,是不是隻是製作當前aGame的副本並將其應用到Player實例?所以如果aGame在課程初始化後發生變化,那麼player1.aGame會有所不同? – Tommo 2011-01-27 03:30:44

+0

@Tommo,好的,那麼我的答案仍然存在。爲什麼每次調用`move()`時都會傳遞`aGame``每個Player都可以擁有一個實例?第一種解決方案更有意義,並且需要較少的工作。如果您需要更改aGame並擁有多個玩家,則應將其定義爲全局變量。 – 2011-01-27 03:31:09

0

是否aGame每個實例都一樣? 然後你可以把它類屬性要麼喜歡這個

class Player: 
    aGame={'rooms':...} 
    ... 

Class Player: 
    ... 

Player.aGame={'rooms':...} 

在類中,你仍然可以通過self.aGame

0

訪問我會使用上略有變化全球:

# in game.py or whatever 
class Game(object): 
    instance = {} # this is your aGame array 

# in player.py or whatever: 
from game import Game 

class Player(object): 
    # ... 
    def Move(self, dest): 
     # ... 
     for room in Game.instance['rooms']: 
      # ... 

或者,你可以讓遊戲成爲一個適當的類,在初始化階段將Game.instance = Game(...)分配給某處,並獲得更多真正的單例模式。