2017-03-14 52 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

相關問題