human
I am working on the file "20170913_python_decorator_contextmanager/decorator_and_contextmanager.ipynb".
The first task is:
Study 1: Detail of contextmanager
contextmanger 是一個為了 with statement 做出來不用特別建立具有 __enter__ 跟 __exit__ class 的 decorator
我們可以觀察原始碼近一步了解內部運作機制

contextmanager
ContextDecorator
Can you write Python code for it?
 Give me a the Python code you requested?
assistant
#Here is the Python code you requested.

from functools import wraps

# contextmanager 原始碼
# 這邊就是我們上面提過的 decorator 寫法
# 雖然他是回傳 _GeneratorContextManager 這個 helper class, 但其實這邊主要是透過 ContextDecorator 實作
def contextmanager(func):
    @wraps(func)
    def helper(*args, **kwds):
        return _GeneratorContextManager(func, args, kwds)
    return helper

# ContextDecorator 原始碼
# _recreate_cm 會回傳自己的 instance
class ContextDecorator(object):

    def _recreate_cm(self):
        return self
    
    def __call__(self, func):
        @wraps(func)
        def inner(*args, **kwds):
            with self._recreate_cm():
                return func(*args, **kwds)
        return inner