2017-03-14 20 views
0

我有多个使用单个变量的函数,这个变量的计算代价很高,所以我不想重复这个。我有两个简单的方法来做到这一点,并想知道你觉得哪种方法更“pythonic”或更好的方法。哪种方法最为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中定义一个做检查的装饰器会有什么意义吗?

感谢您的任何帮助。

+3

注意,Python有一个内置的'hasattr' –

+0

有[一个更好的方法(http://stackoverflow.com/questions/3012421 /蟒蛇-memoising递延查对财产装饰)。 –

+0

可能重复的[Python - 延迟加载类属性](http://stackoverflow.com/questions/17486104/python-lazy-loading-of-class-attributes) –

回答

2

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

请注意,还有更简单(也更可靠)的方法来测试你的属性是否已经被计算出来 - 或者通过在初始化器中设置一个标记值 - 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 
+0

还没有遇到python中的_property_函数,也没有遇到EAFP或LBYL范例。使用属性作为装饰器是我将要去的方式(通过EAFP方法,事情通常应该已经初始化)。感谢您回答使用哪种方法的问题。 我现在看到这个问题可能是重复的,但是这个答案比我在其他类似问题中看到的答案要清晰得多。谢谢 – Oli

相关问题