哪种方法最恐怖?处理变量是否存在

时间:2017-03-14 15:57:06

标签: python methods python-decorators

我有多个使用单个变量的函数,这个变量的计算成本很高,所以我不想重复这个。我有两个简单的方法可以做到这一点,并且想知道你感觉更多" pythonic"或者更好的方法。

class A:

    def __init__(self):
        self.hasAttr = False

    def compute_attr(self):
        self.attr = 10
        self.hasAttr = True #for func2 only

    def func1(self):
        try:
            print self.attr == 10
        except AttributeError:
            self.compute_attr()
            self.func1()

    def func2(self):
        if not self.hasAttr: self.compute_attr()
        print self.attr == 10

a = A()
a.func1()
a.func2()

func1使用一个简单的尝试,除了捕获AttributeError并在这种情况下计算属性。 func2使用存储的布尔值来检查计算是否已经完成。

有没有理由认为一种方法比另一种方法更受欢迎?此外,在func2中定义执行检查的装饰器是否有任何意义?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

基本上你的问题是“should I use EAFP or should I use LBYL”。答案是:这取决于。 try / except块几乎可以自由设置,但是在使用时非常昂贵(当实际出现异常时),而测试具有常量(并且对于这种测试而言相当便宜)成本,所以如果你经常没有属性集你可能更喜欢LBYL解决方案,而如果你确信它已经在大部分时间设置了,那么EAFP可能是更好的选择。

另请注意,还有更简单(且更可靠)的方法来测试您的属性是否已经计算 - 通过在初始化程序中使用sentinel值设置它 - None是一个明显的候选者,除非它恰好是有效值 - 或使用hasattr(obj, attrname)。您还可以使用属性来封装访问,即:

class EAFB(object):

    @property
    def attr(self):
        try:
            return self._attr
        except AttributeError:
            self._attr = costly_computation()
            return self._attr


   def func(self):
       print "attr is %s" % self.attr



class LBYL(object):

    @property
    def attr(self):
        if not hasattr(self, "_attr"):
            self._attr = costly_computation()
        return self._attr


   def func(self):
       print "attr is %s" % self.attr