Why does my contextmanager-function not work like my contextmanager class in python?

后端 未结 1 1883
夕颜
夕颜 2021-01-13 01:58

In my code, I need to be able to open and close a device properly, and therefore see the need to use a context manager. While a context manager is usually defined as a class

相关标签:
1条回答
  • 2021-01-13 02:38

    The example in the documentation for contextmanager is somewhat misleading. The portion of the function after yield does not really correspond to the __exit__ of the context manager protocol. The key point in the documentation is this:

    If an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred. Thus, you can use a try...except...finally statement to trap the error (if any), or ensure that some cleanup takes place.

    So if you want to handle an exception in your contextmanager-decorated function, you need to write your own try that wraps the yield and handle the exceptions yourself, executing cleanup code in a finally (or just block the exception in except and execute your cleanup after the try/except). For example:

    @contextlib.contextmanager
    def cm():
        print "before"
        exc = None
        try:
            yield
        except Exception, exc:
            print "Exception was caught"
        print "after"
        if exc is not None:
            raise exc
    
    >>> with cm():
    ...     print "Hi!"
    before
    Hi!
    after
    
    >>> with cm():
    ...     print "Hi!"
    ...     1/0
    before
    Hi!
    Exception was caught
    after
    

    This page also shows an instructive example.

    0 讨论(0)
提交回复
热议问题