检查是否已定义类变量

时间:2014-06-25 03:33:59

标签: python class oop hasattr

我正在处理一个我有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

1 个答案:

答案 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。