2

残念ながら(選択ではなく) python 2.4を使用しているため、2.5で追加された素晴らしいもの(functoolsなど)は役に立ちません

関数をラップしたいのですが、help(wrapper) を実行すると、ラップする関数のように見えるようにします。

私はこれを行うことで部分的に達成しました

def a():
    """a's docstring"""
    pass

def wrapper():
    a() 
wrapper.func_name = a.func_name #or should this use __name__ ?
wrapper.func_doc = a.func_doc #or should this use __doc__ ?

現在、関数名との docstring のhelp(wrapper)表示を行っています。ハックに感じるだけでなく、これは次のような場合の関数パラメーターをカバーしていません。aa

def b(x, y, z): 
    return a+b+c #or whatever

def wrapper(*args, **kwargs):
    #do something with the arguments
    return b(*args **kwargs)

help(wrapper)b(*args, **kwargs)明らかに、これは私が望むものではないように見えます。dir(a)どこかにネストされていない限り、私を助けることができる属性はないようです。


編集: pypi を使用できる場合は、これに役立つデコレータ モジュールを参照してください。

4

1 に答える 1

4

を使用しfunctools.wrapsます。

引数の指定を偽造するわけではないことに注意してください。あなたはおそらくそれを行うことができます( を使用inspect.getargspecして の引数指定をfoo解決し、次にハッキングしbarます)が、それは従来の方法ではありません。


編集: Python 2.4 を使用しているため、の機能を再実装する必要がありますfunctools.wraps。幸いなことに、実際には非常に単純です。__module__属性、__name__および をコピーするだけで、ラップされた関数の で__doc__ラッパーを更新します。したがって、次のことができます。__dict____dict__

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
WRAPPER_UPDATES = ('__dict__',)

def update_wrapper(wrapper,
                   wrapped,
                   assigned = WRAPPER_ASSIGNMENTS,
                   updated = WRAPPER_UPDATES):
    for attr in assigned:
        setattr(wrapper, attr, getattr(wrapped, attr))
    for attr in updated:
        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
    # Return the wrapper so this can be used as a decorator via partial()
    return wrapper

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)

(参考までに、これは の実際のソース コードですfunctools.wraps。)

于 2012-12-28T19:54:28.313 に答える