2014-10-30 122 views
0

我有一個命令行實用程序,它可以接受各種命令要執行的操作,所以基本上有一個很大的elif鏈會執行什麼命令。有些命令使用變量(我們稱之爲A),因此它必須用值初始化。所以通常我會做:自動初始化變量

self.A = createContent() 
doSomething(self.A.B) 

現在我不想把self.A = createContent()適合每一個地方需要A這樣命令我想問一下,如果有一個Python的方式如何時自動初始化變量例如其NonecreateContent需要時間來處理,所以我不想把它放到每個命令都會執行的構造函數中。

+1

這個問題很混亂。我認爲我們需要更多的背景來了解你想要做什麼,以及爲什麼這樣做纔是正確的做法。例如,什麼樣的對象是'self',你不能只用該對象的初始化方法來定義'A'? – 2014-10-30 07:49:04

+0

我會嘗試更好地展開它:我有一個對象,在對象的單一生命週期中,有時需要「A」,有時根本不需要。我不想使用對象的初始化方法,因爲定義A很昂貴,並不總是需要。同時我不想檢查它是否沒有定義,並在需要'A'的所有地方定義它。 – user1600745 2014-10-30 08:19:36

回答

1

hasattr怎麼樣?

if not hasattr(self, 'A') or self.A is None: 
    self.A = createContent() 
0

如果初始化是昂貴的,因此,你只需要在需要時初始化變量,一個Python的方式是簡單地try使用它,如果失敗,將其初始化。

例如:

try: 
    do_something(self.A) 
except AttributeError: 
    self.A = initialize(self) 
    do_something(self.A) 

您將需要包裝的每一行代碼,在一個情況下,你不能確定它是不是在這樣一個try/except塊尚未定義使用A

另一種方法是每次像@Nsh提出的那樣對A進行明確檢查。但是有人,無論是你還是Python,都必須在某個時候進行檢查。

0

假設你的屬性self.A是某種靜態的對象,我們可以使用property創建它按需實現:

class Something(object): 
    @property 
    def A(self): 
     try: 
      return self._A 
     except AttributeError: 
      self._A=CreateAnA() 
      return self._A 

這樣你就不需要重複檢查。如果您需要這些操作,您可以添加setter等。不利的一面是,創建它時並不明顯(因爲它是讀取屬性的副作用),並且間接查找的性能損失稍微小一些(可以使用__getattr__來避免,但以其他失敗查找爲代價) )。

0

由於上述建議,我想出了這個:

class myClass: 
    def __getattr__(self,name): 
     if name == 'attributeA': 
      print "initializing A" 
      self.attributeA = self.expensiveInit() 
      return self.attributeA 
    def doStuff(self): 
     print self.attributeA 
    def expensiveInit(self): 
     return 'gold' 


a = myClass() 
a.doStuff() 
a.doStuff() 
a.doStuff() 

你認爲這是正確的/ Python的?

+0

'__getattr__'會導致所有未定義的名稱產生'None'。如果你沒有找到任何東西,正常行爲是引發'AttributeError'。 – 2014-10-30 14:10:48