2011-08-19 51 views
3

我正在試驗Python的with語句,我發現在下面的代碼清單中我的__init__方法被調用兩次,而我的__exit__方法被調用一次。這大概意味着如果這段代碼做了任何有用的工作,將會有資源泄漏。Python語句

class MyResource: 
    def __enter__(self): 
     print 'Entering MyResource' 
     return MyResource() 

    def __exit__(self, exc_type, exc_value, traceback): 
     print 'Cleaning up MyResource' 

    def __init__(self): 
     print 'Constructing MyResource' 

    def some_function(self): 
     print 'Some function' 

def main(): 
    with MyResource() as r: 
     r.some_function() 

if __name__=='__main__': 
    main() 

這是程序的輸出:

Constructing MyResource 
Entering MyResource 
Constructing MyResource 
Some function 
Cleaning up MyResource 

我猜這是因爲我做錯了在with聲明,有效地手動調用構造函數。我該如何糾正?

+0

感謝您的答案。現在事後相當明顯:) – CadentOrange

回答

19

您不應該從__enter__返回一個新實例。相反,返回self(針對__enter__被稱爲實例這就是爲什麼__init__()被稱爲兩次 - 你在與聲明__enter__()調用它兩次,一次,一旦這裏有一個正確的版本:。

def __enter__(self): 
    print 'Entering MyResource' 
    return self 
3

我猜測是,你不return MyResource()return self,爲self是已建成類的實例

6

原因__init__被調用兩次,因爲你怎麼稱呼它兩次。

一旦當你在with聲明發起MyResource對象,並再次當with語句調用__enter__這反過來創建並返回MyResource

__enter__方法的不同實例應該返回self代替。

2

你的代碼更改爲:

def __enter__(self): 
    print 'Entering MyResource' 
    return self 

__enter__方法是有你做初始化,而不是創建您的實例,它已經存在(個體經營)。