2016-01-15 41 views
0

我有一個程序模擬王國和其他羣體(在我的代碼中稱爲「派系」)。我在這個程序中跟蹤派系聯盟的地方在哪裏?

class Faction: 
    def __init__(self, name, allies=[]): 
     self.name = name 
     self.allies = allies 

    def is_ally_of(self, other_faction): 
     if self in other_faction.allies: 
      return True 
     else: 
      return False 

    def become_ally(self, other_faction, both_ally=True): 
     """ If both_ally is false, this does *not* also 
      add self to other_faction's ally list """ 
     if self.is_ally_of(other_faction): 
      print("They're already allies!") 
     else: 
      self.allies.append(other_faction) 
      if both_ally == True: 
       other_faction.become_ally(self, False) 

RezlaGovt = Faction("Kingdom of Rezla") 
AzosGovt = Faction("Azos Ascendancy") 

我希望能夠become_ally()方法調用一個派別派別添加到盟友名單,像這樣:

RezlaGovt.become_ally(AzosGovt) # Now AzosGovt should be in RezlaGovt.allies, 
           # and RezlaGovt in AzosGovt.allies 

什麼實際發生的是這樣的:

RezlaGovt.become_ally(AzosGovt) 
# prints "They're already allies!" 
# now AzosGovt is in the allies list of both AzosGovt and RezlaGovt, 
# but RezlaGovt isn't in any allies list at all. 

每當我嘗試調用become_ally()時,代碼應該檢查以確保它們不是盟友。這是不工作的部分。每次我打電話給become_ally()時,它會打印出「他們已經是盟友!」,無論他們是否真的是。

我也試過使用if self in other_faction.allies:,但是那個問題相同。

我強烈懷疑問題在於我使用了self,但我不知道Google會向Google瞭解哪些條款以獲取更多信息。

+0

作爲一個側面說明'如果x在Y:返回否則真:返回FALSE'可以簡化爲'返回X在y' – Neitsa

+0

和'如果x ==真:'是_usually_最好表示爲'如果x:'(它接受任何真實的東西,但Pythonic代碼通常不會在使用'bool'時特別掛斷。 – ShadowRanger

回答

2

You can't use mutable arguments as the default argument to a function.

def __init__(self, name, allies=[]): 

當使用默認情況下,它是相同list每一次,所以它們具有相同的allies;變異的人會改變另一個,因爲他們實際上是同一件事。

更改爲:

def __init__(self, name, allies=None): 
    if allies is None: 
     allies = [] 

另外,無條件地複製allies參數(這樣你就不用擔心對它的引用倖存外班和類下得到的突變):

def __init__(self, name, allies=[]): 
    self.allies = list(allies) # Which also guarantees a tuple argument becomes list 
           # and non-iterable args are rejected 
1

更改此功能。

def is_ally_of(self, other_faction): 
     if other_faction in self.allies: 
      return True 
     else: 
      return False 

檢查自己的數據並不是傳入的對象的。

而且

def __init__(self, name, allies=[]): 

是等待發生的錯誤。您的allies列表將成爲所有實例之間共享的靜態列表。而是使用

def __init__(self, name, allies=None): 
     self.name = name 
     self.allies = allies or [] 
+1

根據精確的設計目標,第一個建議實際上不是問題(措詞是有問題的;通常,是一種共同的東西,所以它不可能是一種方式,但是這個代碼允許單向聯盟) – ShadowRanger

+0

是的,我確實設計了它,以允許單向聯盟,以防一個國家在沒有其他國家知道的情況下暗中宣佈戰爭,或者一些其他可能需要的奇怪情況。 – Somatic

+0

該功能可能更好ed is_ally'。在'become_ally'函數中有意圖的混合。它有邏輯說明我是不是X的盟友,然後把X加到我的盟友列表中,而它應該更像是,如果X不是我的盟友,將X添加到我的盟友列表中。 –

相關問題