2016-03-02 40 views
2

我有多个教学班,像下面的一个方法:从Python中的类方法返回多个值的最有效方法是什么?

@property 
def max_ill(self): 
    maxval = max(self.illarr) 
    maxpts = [idx for idx,val in enumerate(self.illarr) if val==maxval] 
    maxpts = [ self.roomgrid.ptsdict[pt].ptid for pt in maxpts ] 
    return {'data':maxval,"points":maxpts} 

我想什么做的是这个属性分成两个,这样我可以访问max_ill['data']max_ill['points']作为单独的属性一样.max_ill_data.max_ill_points 。这将有助于自动代码竞争,也让我不必记住每个属性返回的内容。但是,正如您在上面看到的,单独调用每个属性会导致一些重复计算。

那么,有没有一种优雅的(非哈希)方式,我可以只运行一次计算并分配两个值?我知道我可以在构造函数中调用一个函数并设置这些值。但是我没有预见到我每次实例化一个类时都需要这些值(因此使用了@property)。

这是一个setter可能有用的地方吗?

+0

你不需要方法或构造函数来定义类变量 –

+0

同意。但是我没有一个简单的类变量。如果您看到第三行,则通过对实例化时设置的名为self.illarr的变量执行一些操作来计算该属性。 –

回答

2

这样做的一种方式是被称为懒惰属性,但也有它的缺点,如果您的self.illarr可能随时间而改变。总之它会是这样的:

def max_ill(self): 
    # Helper function to create the needed values. Not to be used directly 
    maxval = max(self.illarr) 
    maxpts = [idx for idx,val in enumerate(self.illarr) if val==maxval] 
    maxpts = [ self.roomgrid.ptsdict[pt].ptid for pt in maxpts ] 
    # Save the calculated values as attributes 
    self._max_ill_data = maxval 
    self._max_ill_points = maxpts 

@property 
def max_ill_data(self): 
    try: 
     # Get the saved value (raises an AttributeError when not existing) 
     return self._max_ill_data 
    except AttributeError: 
     # We found None, so call the method that creates these and return it afterwards 
     self.max_ill() 
     return self._max_ill_data 

@property 
def max_ill_points(self): 
    try: 
     return self._max_ill_points 
    except AttributeError: 
     self.max_ill() 
     return self._max_ill_points 

所以max_ill负责计算值和属性只返回保存的值,或者如果没有这样的属性,调用创建这些功能。

也有一些库实现了lazyproperties,即使绑定了参数,所以这只是为了说明他们如何简化工作或者如果您不想添加依赖关系。

+0

很快!我没有预见到self.illarr在我的情况下得到改变,但感谢您指出潜在的缺点。 –

+2

在一般情况下,我会建议使用'try:return self._max_ill_date','AttributeError:','self.max_ill()','return self._max_ill_date';使用EAFP模式意味着您不必担心“无”可能是该属性的合法值。或者,你可以创建一个私有类变量'__sentinel = object()'并将其用作'getattr'默认值并且测试'ret是self .__ sentinel',所以你有一个唯一的“not found”值真正的价值。 – ShadowRanger

+1

@ShadowRanger - 我总是忘记[EAFP](https://docs.python.org/3.5/glossary.html#term-eafp)...我会编辑答案。感谢您指出这一点。 – MSeifert

相关问题