检查类变量是否已定义

0 投票
1 回答
1781 浏览
提问于 2025-04-18 10:58

我在处理一个场景,里面有一个叫做Foo的python类。Foo类做了很多复杂的计算,这些计算我不会随便进行,只有在必要的时候才会执行。所以,当我为其中一个复杂计算定义一个获取方法时,我该如何确保这个计算方法(这里是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()函数来实现的,但我觉得这种方式真的很笨拙。有没有更优雅的python方式来做这件事呢?

我想到的一个替代方法是在我的init()函数中,定义所有我可能在类中使用的变量,初始值设为空列表。然后通过检查big_calc_result是否是空列表来判断self.bigcalculation()是否已经执行过。这种方法更好吗?

相关问题:Python允许我在类中动态定义变量。但这算不算不好的编程习惯呢?

补充:回想起来,我发现使用异常处理也是应对这种情况的另一种方法。这可能是一种更符合python风格的做法。

def get_big_calc_result(self):
    try:
        return self.big_calc_result;
    except AttributeError:
        self.bigcalculations();
        return self.big_calc_result;

这个问题的答案很有用:检查Python中的成员是否存在

1 个回答

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

当然,如果用属性不太直观,你也可以根据你想提供的接口来调整这些内容。关键在于把结果缓存到一个以下划线开头的变量里,这表示“这是实现的细节——如果你去碰它,你就得承担未来代码出问题的风险”。

撰写回答