2016-04-15 95 views
1

我正在編寫一個程序,您可以在其中放置主隊,客隊以及比賽結果。我想讓團隊的數據根據​​這個改變,大部分都會改變。但我不能讓「點數」,「淨勝球」和「打球」(比賽)改變!這是我寫到目前爲止代碼:使用其他屬性的值進行計算的屬性

class team: 
    def __init__(self, name, wins, drawn, losses, goals_for, goals_against): 
     self.name = name 
     self.wins = int(wins) 
     self.drawn = int(drawn) 
     self.losses = int(losses) 
     self.goals_for = int(goals_for) 
     self.goals_against = int(goals_against) 
     self.goals_difference = (self.goals_for - self.goals_against) 
     self.points = ((self.wins * 3) + self.drawn) 
     self.played = (self.wins + self.drawn + self.losses) 
    def __repr__(self): 
     return 'Name:{} P:{} W:{} D:{} L:{} GF:{} GA:{} GD:{} PTS:{}'.format(self.name, self.played, self.wins, self.drawn, self.losses, self.goals_for, self.goals_against, self.goals_difference, self.points)  

detroit_red_wings = team("Detroit", 1, 0, 3, 4, 5) 
los_angeles_kings = team("LA", 0, 1, 4, 3, 7) 
toronto_maple_leafs = team("Toronto", 1, 2, 2, 3, 6) 

teamlist = [detroit_red_wings, los_angeles_kings, toronto_maple_leafs] 
print(teamlist) 

class data_input: 
    def home_team_input(self): 
     home_team = input("Type in the home team: ") 
     for i in teamlist: 
      if i.name == home_team: 
       return i 
    def away_team_input(self):   
     away_team = input("Type in the away team: ") 
     for t in teamlist: 
      if t.name == away_team: 
       return t 
    def result_input(self): 
     goals_home_team = int(input("Type in the number of goals made by the home team: ")) 
     goals_away_team = int(input("Type in the number of goals made by the away team: ")) 
     return (goals_home_team, goals_away_team) 

def adding_result(): 
    home_team = data_input.home_team_input() 
    away_team = data_input.away_team_input() 
    goals_home_team, goals_away_team = data_input.result_input() 

    home_team.goals_for += goals_home_team 
    home_team.goals_against += goals_away_team 
    away_team.goals_for += goals_away_team 
    away_team.goals_against += goals_home_team 

    if goals_home_team > goals_away_team: 
     home_team.wins += 1 
     away_team.losses += 1 
    if goals_home_team < goals_away_team: 
     away_team.wins += 1 
     home_team.losses += 1 
    if goals_home_team == goals_away_team: 
     home_team.drawn += 1 
     away_team.drawn += 1 

data_input = data_input() 
adding_result() 
print(teamlist) 

我寫的屬性中的指導類team__init__方法,正如你所看到的點依賴於wins。這一切都適用於我創建對象的時候,但是當我將新遊戲的結果放入points時不會改變(playedgoals_difference也不會)。這令我感到驚訝,因爲當我在input函數中輸入遊戲結果時,其他屬性會發生變化。

回答

0

pointsgoals_difference,並且played不更新,因爲你__init__方法不再次,一旦你更新其他性能運行 - 你只是用他們的新價值明確更新的其他屬性。請注意,這些未更新的屬性由分配,而不是通過引用,因此對象無法知道這些屬性應該更新,除非您明確這樣做。

有幾件事你可以做 - 一個簡單的選擇可能是提供一種方法來更新聚合屬性,您可以在明確更改其他屬性後調用。我會將所有屬性簡單地作爲其他屬性的數學表達式(如points,goals_differenceplayed),並將它們從初始化方法中刪除。而是調用一個小方法就像update_aggregates如果你真的需要這些屬性可能看起來像這樣

def update_aggregates(self): 
    self.goals_difference = (self.goals_for - self.goals_against) 
    self.points = ((self.wins * 3) + self.drawn) 
    self.played = (self.wins + self.drawn + self.losses) 

編輯是:在簡單無視我的嘗試,由史蒂夫·科恩提出的解決方案是通過各種手段更好 - 使用@property可確保您的值始終得到適當更新,而無需手動調用。

+0

這工作得很好!非常感謝你!! –

+0

有一個單獨的更新功能是非常糟糕的。計算結果應該通過@p​​roperties或函數訪問,以便它們對於其他項目的當前狀態始終準確。 –

+0

@SteveCohen好點,我目前無法更新我的答案,但我會盡快解決,但我試圖做到簡單,但在這種情況下,簡單只是一種不好的做法。 – miradulo

3

如果更新team類來計算字段屬性,那麼屬性函數將始終返回正確的結果。如果您嘗試設置這些屬性,您也會收到錯誤,因爲它們不可設置,即它們是對其他設置數據進行計算的結果。

class team: 
    def __init__(self, name, wins, drawn, losses, goals_for, goals_against): 
     self.name = name 
     self.wins = int(wins) 
     self.drawn = int(drawn) 
     self.losses = int(losses) 
     self.goals_for = int(goals_for) 
     self.goals_against = int(goals_against) 

    @property 
    def goals_difference(self): 
     return self.goals_for - self.goals_against 

    @property 
    def points(self): 
     return self.wins * 3 + self.drawn 

    @property 
    def played(self): 
     return self.wins + self.drawn + self.losses 

    def __repr__(self): 
     return 'Name:{} P:{} W:{} D:{} L:{} GF:{} GA:{} GD:{} PTS:{}'.format(
      self.name, self.played, self.wins, self.drawn, self.losses, 
      self.goals_for, self.goals_against, self.goals_difference, 
      self.points) 

我還要考慮使W/L/d和GF/GA初始化tupples或字典而不是通過5個變量初始化。

+1

'return'不是一個函數,所以儘量不要讓它看起來像一個 – Eric

+0

30年的C習慣很難死。刪除了返回值中多餘的括號。奇怪的是,PEP8或者pylint都沒有標記這一點。 –

+0

更新我的回答,以反映這應該是公認的答案-_- – miradulo