我正在处理一个我有python类Foo的场景。 Foo,其中包括许多大的计算,除非需要,否则我不会这样做。因此,当我为其中一个大型计算定义getter方法时,如何确保与计算相对应的方法(此处为bigcalculation())已经运行?
class Foo:
def __init__(self):
#initialize some stuff
def bigcalculation(self):
#perform calculation
self.big_calc_result=[big list of numbers];
def get_big_calc_result(self):
if hasattr(self,'big_calc_result')==False:
self.bigcalculations();
return sef.big_calc_result;
如果它运行一次,我不希望它再次运行。而且我不希望调用者必须跟踪它是否已经运行过一次。
现在,我使用上面的hasattr()函数来做,但我认为这是一个非常难看的方法。有更优雅的pythonic方式吗?
我能想到的另一种方法是,在我的 init ()函数中,将我在类中使用的所有变量定义为空列表。然后检查big_calc_result是否为空列表以确定self.bigcalculation()是否已经运行。这是一种更好的方法吗?
相关问题:Python允许我在类中动态定义变量。但这是不好的编程习惯吗?
编辑:回想起来,我还发现使用异常也可以是处理这种情况的另一种方法。这可能是一种更加pythonic的做事方式。
def get_big_calc_result(self):
try:
return self.big_calc_result;
except AttributeError:
self.bigcalculations();
return self.big_calc_result;
这个问题的答案很有用: Checking for member existence in Python
答案 0 :(得分:2)
您可以记住结果并将其存储为属性:
class Foo(object):
def __init__(self):
self._big_calc_result = None
@property
def big_calc_result(self):
if self._big_calc_result is not None:
return self._big_calc_result
else:
self._big_calc_result = self.big_calc_run()
return self._big_calc_result
def big_calc_run(self):
time.sleep(10) # Takes a long time ...
现在,您只需初始化类并获得结果:
f = Foo()
x = f.big_calc_result
y = f.bic_calc_result # Look mom, this happened really quick
当然,如果不太直观,您不必使用该属性,并且您可以在此处更改内容以适应您尝试提供的API。真正的关键在于将结果缓存在带有下划线的变量中,也就是说"这是一个实现细节 - 如果你搞砸了,你应该在将来某个时候让代码中断# 34。