13

与えられた関数:

def func(f1, kw='default'):
    pass
bare_argspec = inspect.getargspec(func)

@decorator
def func2(f1, kw='default'):
    pass
decorated_argspec = inspect.getargspec(func2)

どうすればそのようなデコレータを作成できますbare_argspec == decorated_argspecか?

(理由については、decorated関数を呼び出すフレームワークがargspec検査を行って何を渡すかを選択するため、デコレータはうまく再生するために同じargspecを保持する必要があります。#pythonでこの質問をしたとき、私は長くなりましたフレームワークがうまくいかない理由についてのスピーチ、それは私が探しているものではありません;私はここで問題を解決する必要があります。また、私も答えに興味があります)

4

3 に答える 3

12

Michele Simionato のデコレータ モジュールには、関数 argspecs を保存するデコレータと呼ばれるデコレータがあります。

import inspect
import decorator

def func(f1, kw='default'):
    pass
bare_argspec = inspect.getargspec(func)
print(bare_argspec)
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',))

@decorator.decorator
def mydecorator(func,*args,**kw):
    result=func(*args,**kw)
    return result

@mydecorator
def func2(f1, kw='default'):
    pass
decorated_argspec = inspect.getargspec(func2)
print(decorated_argspec)
# ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',))

assert(bare_argspec==decorated_argspec)
于 2010-09-16T18:09:45.473 に答える
2

デコレータモジュールがあります:

from decorator import decorator
@decorator
def trace(func, *args, **kw):
    print 'calling', func, 'with', args, kw
    return func(*args, **kw)

これによりtrace、装飾された関数と同じ argspecs を持つデコレータが作成されます。例:

>>> @trace
... def f(x, y=1, z=2, *args, **kw):
...     pass

>>> f(0, 3)
calling f with (0, 3, 2), {}

>>> from inspect import getargspec
>>> print getargspec(f)
ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2))
于 2010-09-16T18:11:04.333 に答える
0

functools.update_wrapper()および/またはfunctools.wraps()十分ですか?

于 2010-09-16T18:09:10.733 に答える