title: Python: How to correctly create and destroy resources using the contextmanager descriptor pattern
body: <p>I implement the creation and destruction of resources in the following way:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>My question relates to the last line of code:</p>
  
  <p><strong>Why is the context and/or resource still available although the scope of the with-statement was left which should have called the __exit__ function?</strong></p>