2015-05-12 32 views
0

我實現以下列方式資源的創建和銷燬破壞資源:的Python:如何正確地創建和使用contextmanager描述符模式

import weakref 

class Context(object): 
    def __init__(self): 
     self.resource = object() # sample resource creation 

    def __del__(self): 
     self.resource = None # destroy resource but keep attribute (compare with 'del') 

    def get_resource(self): 
     """ 
     return a proxy of the resource so that only this context 
     instance holds a valid instance and can therefore destroy it 
     when it wants to no matter if another 'reference' is hold 
     elsewhere 
     """ 
     return weakref.proxy(self.resource) 

class ContextManager(object): 
    def __init__(self): 
     self._context = None # create attribute 

    def __enter__(self): 
     self._context = Context() 
     return self._context # make the context available in the 'with .. as ..' statement 

    def __exit__(self, type, value, traceback): 
     self._context = None 


if __name__ == "__main__": 

    with ContextManager() as c: 
     print(c.get_resource()) # do something with resource 

    """ 
    although we have left the scope of the with statement this print 
    still executes and a check with gc.get_referrers still shows the 
    references in use 
    """ 
    print(c.resource) 

我的問題涉及到代碼的最後一行:

爲什麼上下文和/或資源仍然可用,雖然這應該叫__exit__功能與語句留下的範圍是什麼?

回答

0

我錯了,當我認爲我從C/C知道一個範圍的行爲與++蟒蛇到正常工作。我的問題的解決方案是返回上下文的weakref.proxy:

def __enter__(self): 
    self._context = Context() 
    return weakref.proxy(self._context)