python笔记整理-6. 装饰器

让函数既是装饰器又是上下文管理器

现在定义一个上下文管理器可以转成装饰器.

比如django里的一个例子

@transaction.atom()
def ....
# 或者
with transaction.atom():
    ...

为什么可以这样,看django的源代码

from django.utils.decorators import ContextDecorator
class Atomic(ContextDecorator):

也就是说利用了一个上下文的声明器,在contextlib里也提供了大致的内容如下

    class ContextDecorator(object):
        """
        A base class that enables a context manager to also be used as a decorator.
        """
        def __call__(self, func):
            @wraps(func, assigned=available_attrs(func))
            def inner(*args, **kwargs):
                with self:
                    return func(*args, **kwargs)
            return inner

这样就能在定义一个上下文管理器的同时让他变成装饰器.

注意,在python3.2以后ContextDecorator已经包含在python库里了.