2012-11-26 45 views
1

例如回來後,我有這樣的代碼:獲得通過__enter__在__exit__

with MyClass() as x: 
    print 'I have only {0}'.format(x) 
    with MyClass() as y: 
     print 'I have {0} and {1}'.format(x, y) 
    print 'Again only {0}'.format(x) 

xy都應該相應with塊退出後去初始化。 xy也不是MyClass的實例。

__exit__只有三個參數,每個參數都是無(如​​果沒有提供異常)。

我如何確定__exit__哪個塊剛剛退出,以及__enter__返回的值是什麼?

(N.B.代碼應該是線程安全的)。


例子:

class MyClass(object): 
    def __enter__(self): 
     if moon_phase > 0: 
      return 123 
     else: 
      return 456 
    def __exit__(self): 
     number = what_was_returned_by_enter() 
     print 'End of block with', number 


with MyClass() as x: 
    print x # 123 
    with MyClass() as y: 
     print x, 'and', y # 123 and 456 
    # printed "End of block with 456" 
    print x # 123 
# printed "End of block with 123" 
+0

只要保持跟蹤你通過將其存儲在一個實例變量返回的值。 – sloth

回答

3

既然你有一個自定義類處理您的背景下,self將上下文管理器實例。

您需要檢查其狀態(存儲在__init__()創建時間或調用__enter__()時)以確定您剛剛退出的哪一個。

下面的示例存儲的__enter__實例上的返回值,以便可以再次找回它,當__exit__被稱爲:

class MyClass(object): 
    def __enter__(self): 
     if moon_phase > 0: 
      self.returnval = 123 
     else: 
      self.returnval = 456 
     return self.returnval 

    def __exit__(self, *args): 
     number = self.returnval 
     print 'End of block with', number 
+0

但是,如果我編寫嵌套語句,'self.returnval'將在子塊的開始處重新編寫,我將從父塊中丟失值。 – werehuman

+1

@werehuman:不,除非您在您的課程或方法中使用可變默認參數,否則這是不可能的。每個上下文管理器都是獨立的實例。如果您需要幫助解決*爲什麼*您的代碼不適用於您的特定情況,請使用示例代碼更新您的問題。 –

+1

你是對的,它創造了新的實例。我將閱讀手冊。 – werehuman