2

我如何定义一个装饰器decor来完成这项工作?有很多关于这个的帖子,但我仍然没有找到解决方案。也许这是一个非常糟糕的主意。

示例 1,编写一个在应用装饰器之前中断的函数:

defaults = {'a': 1, 'b': 2}

@decor(defaults)
def f(x):
    print(x, a, b)

示例 2:

defaults = {'a': 1, 'b': 2}

@decor(defaults)
def fun(x):
   print(locals())

f(3)

应该给

{'b': 2, 'x': 3, 'a': 1}

或者更清楚一点,我希望装饰者修改签名,以便help(f)给出

Help on function f in module __main__:

f(x, a=1, b=2)
4

2 回答 2

1

好的,你已经被警告过这是不安全的东西,但只是为了好玩,这个装饰器必须工作,无论装饰函数是否接收 kwargs

import inspect as insp

def modify(f, defaults):
    lines = insp.getsourcelines(f)[0]
    lines.pop(0) # remove decorator heading
    for k, v in defaults.items():
        lines.insert(1, '    %s = %s\n' % (k, v))
    exec ''.join(lines)
    return locals()[f.__name__]

def decor(defaults):
    def wrap(f):
        def wrapped_f(*args):
            new_f = modify(f, defaults)
            return new_f(*args)
        return wrapped_f
    return wrap
于 2013-07-05T17:04:14.760 回答
0

不确定这是否是您真正想要的,但这里有

defaults = {'a': 1, 'b': 2}

def decor(**kw_dec):
    def decorate(func):
        def ret(*args, **kwargs):
            func(*args, **dict(kw_dec, **kwargs))
        return ret
    return decorate


def fun(*args, **kwargs):
    print(locals())

fun = decor(**defaults)(fun)
fun(3)

{'args': (3,), 'kwargs': {'a': 1, 'b': 2}}
于 2013-07-05T17:00:29.293 回答