2013-03-03 68 views
0

我的一個類對對象集合進行了大量聚合計算,然後分配一個適合特定對象的屬性和值:即,Python:顯示分配給類對象的屬性代碼

class Team(object): 
    def __init__(self, name): # updated for typo in code, added self 
     self.name = name 

class LeagueDetails(object): 
    def __init__(self): # added for clarity, corrected another typo 
     self.team_list = [Team('name'), ...] 
     self.calculate_league_standings() # added for clarity 


    def calculate_league_standings(self): 
     # calculate standings as a team_place_dict 
     for team in self.team_list: 
      team.place = team_place_dict[team.name] # a new team attribute 

我知道,只要calculate_league_standings已運行,每隊有team.place。我希望能夠做的是掃描代碼class Team(object)並閱讀所有屬性,這些屬性都是由類方法創建的,也是由對類對象進行操作的外部方法創建的。我只是爲了查看屬性名稱是什麼而輸入for p in dir(team): print p有點不舒服。我可以在團隊__init__中定義一堆空白attributes。例如。

class Team(object): 
    def __init__(self, name): # updated for typo in code, added self 
     self.name = name 
     self.place = None # dummy attribute, but recognizable when the code is scanned 

這似乎是多餘的有calculate_league_standings回報team._place然後添加

@property 
def place(self): return self._place 

我知道我可以在上面class Team,這是顯而易見的解決方案發表意見的屬性列表,但我覺得好像有這裏必須是最好的做法,這裏有一些pythonic和優雅的東西。

+0

請說清楚這句話_「然後賦值和屬性和值適合於_。對我來說,這意味着什麼 – eyquem 2013-03-03 18:51:51

+0

因此,如果'ld = LeagueDetails()',然後'ld.calculate_league_standing()'。它計算'place'值並將該值賦予每個'team'的屬性'place'。當我查看'class Team(object)'的代碼時,它沒有顯示明顯的事情。每個團隊都有一個'team.place'屬性。 – Cole 2013-03-03 18:57:54

+3

你寫的代碼是錯誤的,因爲你在方法外使用'self'。你的行'self.team_list = ...'不起作用。你爲什麼不做一個'__init__'方法來設置'self.team_list'並且調用'calculate_league_standing'? – BrenBarn 2013-03-03 19:07:09

回答

1

如果我瞭解你的問題,你想跟蹤初始化後添加了一個實例的屬性。如果是這樣的話,你可以使用這樣的事情:

#! /usr/bin/python3.2 

def trackable (cls): 
    cls._tracked = {} 

    oSetter = cls.__setattr__ 
    def setter (self, k, v): 
     try: self.initialized 
     except: return oSetter (self, k, v) 
     try: self.k 
     except: 
      if not self in self.__class__._tracked: 
       self.__class__._tracked [self] = [] 
      self.__class__._tracked [self].append (k) 
     return oSetter (self, k, v) 
    cls.__setattr__ = setter 

    oInit = cls.__init__ 
    def init (self, *args, **kwargs): 
     o = oInit (self, *args, **kwargs) 
     self.initialized = 42 
     return o 
    cls.__init__ = init 

    oGetter = cls.__getattribute__ 
    def getter (self, k): 
     if k == 'tracked': return self.__class__._tracked [self] 
     return oGetter (self, k) 
    cls.__getattribute__ = getter 

    return cls 

@trackable 
class Team: 
    def __init__ (self, name, region): 
     self.name = name 
     self.region = region 

#set name and region during initialization 
t = Team ('A', 'EU') 

#set rank and ELO outside (hence trackable) 
#in your "aggregate" functions 
t.rank = 4 # a new team attribute 
t.ELO = 14 # a new team attribute 

#see witch attributes have been created after initialization 
print (t.tracked) 

如果我不明白的問題,請你說明我得到了這部分錯誤的。

+0

這段代碼創建了我真正感激的各種想法。當我在'__init __(self)'外分配屬性時,我這樣做只是爲了能夠顯示結果。謝謝! – Cole 2013-03-03 19:50:33

+0

如果您可以詳細闡述實際需求,我會很樂意提供更精確的幫助。 – Hyperboreus 2013-03-03 19:53:09

1

由於Python的動態性,我不相信你的問題有一個通用的答案。可以通過多種方式設置實例的屬性,包括純分配,setattr()和寫入__dict__。編寫一個工具來靜態分析Python代碼並通過分析所有這些方法正確地確定類的所有可能的屬性將是非常困難的。

在您的特定情況下,作爲程序員,你知道class Team將在許多情況下,位置屬性,這樣你就可以決定是明確的,寫它的構造像這樣:

class Team(object): 
def __init__(name ,place=None): 
    self.name = name 
    self.place = place 

我會說有不需要定義簡單屬性的屬性,除非您希望在讀取或寫入時發生副作用或派生。

+0

我的問題全是關於可讀性的,而你的答案反映了我一般的傾向。我不想寫一個工具,而是寫更好的代碼。我越來越擔心,爲一個類對象分配一長串「屬性」是一種糟糕的風格,因爲這些「屬性」最終會成爲一種「神祕肉」 - 技術術語。你不能只是去班級代碼來提醒你預期的預期'屬性'的完整列表。 – Cole 2013-03-03 19:41:09

+0

我選擇了其他答案,因爲它爲我正在進行的實際項目創建的值。雖然你的回答只是我想要的討論類型。 – Cole 2013-03-03 20:34:27