2013-03-18 15 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 
相关问题