保留signatu的Python decorator(闭包版本)

2024-04-25 23:42:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我的decorator是“闭包式”的;它在返回被修饰的函数之前做一些工作。你知道吗

借用这个著名的问题:Preserving signatures of decorated functions

def args_as_ints(f):

    time.sleep(1) # hard at work

    def g(*args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return f(*args, **kwargs)
    return g

functools.wraps在python2中不保留签名。你知道吗

from functools import wraps

def args_as_ints(f):

    time.sleep(1) # hard at work

    @wraps(f) 
    def g(*args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return f(*args, **kwargs)
    return g


@args_as_ints
def funny_function(x, y, z=3):
    """Computes x*y + 2*z"""
    return x*y + 2*z

help(funny_function)

演出

Help on function funny_function in module __main__:

funny_function(*args, **kwargs)
    Computes x*y + 2*z

decorator模块似乎不支持这种装饰器样式。你知道吗

同样相关:Preserve Signature in Decorator python 2


Tags: inforreturntimedefasargsfunction
2条回答

您可以使用^{}模块。你知道吗

请记住,wrapt修饰符与标准python修饰符具有不同的接口。我强烈建议您阅读^{} documentation。总之,这里是用wrapt.decorator实现装饰器的基本方法:

import wrapt

def args_as_ints(f):
    time.sleep(1) # hard at work

    @wrapt.decorator
    def g(f, instance, *args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return f(*args, **kwargs)

    return g(f)  # apply the decorator to the function

请注意,我的实现完全忽略了instance参数,因此对于实例方法它无法正常工作。你知道吗

但是,它确实保留了修饰函数的签名:

Help on function funny_function in module __main__:

funny_function(x, y, z=3)
    Computes x*y + 2*z

设法在这里找到答案:https://decorator.readthedocs.io/en/latest/tests.documentation.html#dealing-with-third-party-decorators

def args_as_ints(f):

    time.sleep(1)

    def g(*args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return f(*args, **kwargs)

    return decorator.FunctionMaker.create(
        f, 'return decfunc(%(signature)s)',
        dict(decfunc=g, __wrapped__=f))

相关问题 更多 >