2

代わりに使用する新しいデコレータを作成したいと思います。それは、@wraps(f)魔法@wraps(f)が行うことと他のことを行います。どうすればいいですか?

具体的には、次の形式のデコレータがいくつかあります。

def decorator(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        # does some stuff in here
        return f(*args, **kwargs)
    if not hasattr(wrapper, '_first_line'):
        wrapper._first_line = inspect.getsourcelines(f)[1]
    return wrapper

のようなデコレータを作成できるように思わ@wraps_with_first_line(f)@wraps(f)ますif not hasattr(wrapper, '_first_line'): wrapper._first_line = inspect.getsourcelines(f)[1]

4

2 に答える 2

3

__wrapped__ラップされた関数の単一の属性を追加するよりも、ラップされた関数を指す属性 を追加するというグッド プラクティスに従う必要があります。の新しいバージョンfunctools.wraps()はこれが自動的に行われますが、3.2 よりも古いバージョンの Python を使用している場合は、簡単に拡張wraps()して を追加することもでき__wrapped__ます。

def my_wraps(wrapped, **kwargs):
    def decorator(wrapper):
        functools.update_wrapper(wrapper, wrapped, **kwargs)
        wrapper.__wrapped__ = wrapped
    return decorator

編集:これは、おそらく乗算装飾された関数から元の関数を抽出する関数です:

def orig_function(f):
    try:
        while True:
            f = f.__wrapped__
    except AttributeError:
        return f
于 2012-04-05T16:08:26.930 に答える
1

追加したいものがラップされたオブジェクトの属性ではない場合は、これを使用できます。

def wraps_with_first_line(f):
    def wrap(wrapper):
        wrapper = wraps(f)(wrapper)
        if not hasattr(wrapper, '_first_line'):
            wrapper._first_line = inspect.getsourcelines(f)[1] 
        return wrapper
    return wrap

すでにラップされたオブジェクトの属性である場合は、Sven の方法を使用します。

于 2012-04-05T16:12:31.233 に答える