2013-03-18 46 views
3

我創建了一個類,其屬性都是可選的。目前,我的代碼完全受try: ... except AttributeError: ...塊影響,但我想知道這是否是最好的方法。一個類的屬性都是可選的

我現在正在改變我的方法,將None類型用於每個未知屬性,這使我的代碼在我看來更好看,但我仍然想知道是否有更好的方法,或者我是否必須處理測試這是與選擇性來的。

我試圖做一個Coordinates,它必須以特殊方式進行修改,並且通常不會事先知道,但必須在其他實例的幫助下進行計算,這就是爲什麼值必須是可選的。

很高興聽到您的經驗和建議。

編輯:

謝謝大家的回答!你們都很快......雖然我很慢,對不起。 由於這個話題非常抽象,我不得不花更多的時間來思考它。 我接受你的答案,Ethan作爲解決方案,因爲我認爲這是我將要研究的下一個方向。我只是張貼一些代碼來澄清以下陳述。我對__add__ -routine舊的代碼是這樣的:

def __add__(self, other): 
    """Add the given *masses* and calculate the resulting center of 
    gravity. *other* must be a :meth:`putzmeister.Masse` instance or 0. 
    """ 
    if other == 0: 
    result = self.copy() 
    result.label = None 
    return result 
    elif not isinstance(other, type(self)): 
    raise TypeError('Error: second operand is not a Masse instance') 
    mass = self.masse + other.masse 
    result = type(self)(masse=mass) 
    try: result.x = (self.x*self.masse + other.x*other.masse)/mass 
    except AttributeError: pass 
    try: result.y = (self.y*self.masse + other.y*other.masse)/mass 
    except AttributeError: pass 
    try: result.z = (self.z*self.masse + other.z*other.masse)/mass 
    except AttributeError: pass 
    result._set_categories(self, other, action='add') 
    return result 

現在看起來是這樣的:

def __add__(self, other): 
    """Overwrite operator "+": add the given masses and calculate the resulting center of 
    gravity. 
    """ 
    if other == 0: 
    result = self.copy() 
    result.label = None 
    return result 
    elif not isinstance(other, type(self)): 
    raise TypeError('Error: second operand is not a Masse instance') 
    mass = self.masse + other.masse 
    result = type(self)(masse=mass) 
    for a in ('x','y','z'): 
    c1 = getattr(self, a) 
    c2 = getattr(other,a) 
    if c1 is None or c2 is None: setattr(result, a, None) 
    else: setattr(result, a, (c1*self.masse + c2*other.masse)/mass) 
    result._set_categories(self, other, action='add') 
    return result 

的無類型將是好的爲<unset state>。現在的問題是,0是所有座標的有效值,所以我總是必須檢查if attribute is not None而不是if attribute這將是我認爲最好的代碼可以得到的。

但我的夢想是,在分配z = x + y我的代碼將能夠首先檢查如果Z存在並具有正確的類型,然後如果是它設置可以用數學推導x和y的值語句(例如,對於y:如果z具有某些屬性且x具有相同的屬性...)如果z不存在,則創建它並設置所有可設置的值。不太確定這樣的事情是否可以完成...

再次,謝謝大家的回答。

+6

你可以發佈你的類的小(或簡化的)例子? – theJollySin 2013-03-18 22:30:36

+1

如果你的類的所有屬性實際上是可選的,你可以使用'dict'或'defaultdict'來代替(或從其中的一個類派生你的類)。 – 2013-03-18 22:40:12

+0

並不總是最好的主意,但是你可以重載__getattr__。 – ebarr 2013-03-19 00:17:14

回答

1

他們真的不需要在那裏,或者他們應該在那裏默認值?無論哪種方式,似乎你已經學會了更好的方法 - 最好是同一類的所有實例具有相同的屬性。

使用None是處理未初始化的名稱的標準方法,但如果None可以作爲一個有效的值,你可以讓你自己:

class UnInit(object): 
    """ 
    No value yet given to this attribute 
    """ 

class Coordinate(object): 
    x = UnInit 
    y = UnInit 
    z = UnInit 
相關問題