漂亮的Python装饰器

漂亮的Python装饰器,python,decorator,Python,Decorator,我怎样才能写出一个好的装饰师呢 具体问题包括:与其他装饰程序的兼容性、签名的保存等 如果可能的话,我希望避免依赖于装饰模块,但是如果有足够的优势,那么我会考虑。 相关的 -更具体的问题。这里的答案是使用第三方decorator模块,用@decorator.decorator注释decorator 使用functools保留名称和文档。签名不会被保留 直接从 编写一个好的装饰程序与编写一个好的函数没有什么不同。这意味着,理想情况下,使用docstring并确保decorator包含在您的测试框架

我怎样才能写出一个好的装饰师呢

具体问题包括:与其他装饰程序的兼容性、签名的保存等

如果可能的话,我希望避免依赖于装饰模块,但是如果有足够的优势,那么我会考虑。 相关的

  • -更具体的问题。这里的答案是使用第三方decorator模块,用@decorator.decorator注释decorator

使用functools保留名称和文档。签名不会被保留

直接从


编写一个好的装饰程序与编写一个好的函数没有什么不同。这意味着,理想情况下,使用docstring并确保decorator包含在您的测试框架中

您肯定应该在标准库中使用
装饰器
库,或者更好地使用
functools.wrapps()
装饰器(从2.5版开始)

除此之外,最好是让你的装饰师集中精力,精心设计。如果您的装饰程序需要特定的参数,请不要使用
*args
**kw
。填写您期望的参数,而不是:

def keep_none(func):
    def _exec(*args, **kw):
        return None if args[0] is None else func(*args, **kw)

    return _exec
。。。使用

def keep_none(func):
    """Wraps a function which expects a value as the first argument, and
    ensures the function won't get called with *None*.  If it is, this 
    will return *None*.

    >>> def f(x):
    ...     return x + 5
    >>> f(1)
    6
    >>> f(None) is None
    Traceback (most recent call last):
        ...
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    >>> f = keep_none(f)
    >>> f(1)
    6
    >>> f(None) is None
    True"""

    @wraps(func)
    def _exec(value, *args, **kw):
        return None if value is None else func(value, *args, **kw)

    return _exec

在维基上回答你自己的问题是一件好事。
def keep_none(func):
    """Wraps a function which expects a value as the first argument, and
    ensures the function won't get called with *None*.  If it is, this 
    will return *None*.

    >>> def f(x):
    ...     return x + 5
    >>> f(1)
    6
    >>> f(None) is None
    Traceback (most recent call last):
        ...
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
    >>> f = keep_none(f)
    >>> f(1)
    6
    >>> f(None) is None
    True"""

    @wraps(func)
    def _exec(value, *args, **kw):
        return None if value is None else func(value, *args, **kw)

    return _exec