我有多个类,其方法如下:
@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
和{{1} }。这将有助于自动代码竞争,也让我不必记住每个属性返回的内容。但是,正如您在上面所看到的,单独调用每个属性将导致重复某些计算。
那么,是否有一种优雅(非hacky)方式,我可以只运行一次计算并分配两个值?我知道我可以调用.max_ill_points
构造函数中的函数并设置这些值。但是,每当我实例化一个类(因此使用def __init__
)时,我都不会预见到自己需要这些值。
这是一个setter可能有用的地方吗?
答案 0 :(得分: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
,即使使用了绑定参数,所以这只是为了说明它们如何简化工作,或者你是否不想添加依赖项。