カスタムデコレータがあり、それが修飾された関数のdocstringを適切に処理するとします。問題は、私のデコレータが引数を追加することです。
from functools import wraps
def custom_decorator(f):
@wraps(f)
def wrapper(arg, need_to_do_more):
'''
:param need_to_do_more: if True: do more
'''
args = do_something(arg)
if need_to_do_more:
args = do_more(args)
return f(args)
return wrapper
引数が実際には装飾された関数に渡されず、ラッパーによって使用されていることがわかります。
追加の引数の文書化を適切に処理するにはどうすればよいですか?ラッパーが追加の引数を取ることは良い習慣ですか、それとも避けるべきですか?
または、次のような別のソリューションを使用する必要があります:
デコレータを使用してメソッドのシグネチャを変更することは、ほとんどの場合違反するものです 最小の驚きの原則 :
最小驚きの原則では、操作の名前と他の手がかりに基づいて、一部の操作を実行した結果は明白で一貫性があり、予測可能である必要があると述べています。
私が思いつく可能性のある例外は:
@property
です。それにもかかわらず、通常、デコレータは通常、関数をデコレートするために実装されます( Decorator pattern のように、デコレータ機能の作成者 この類似性に反対 )。パラメータ)は変更されません。
新しいパラメーターを暗黙的に追加する代わりに、これを明示的にすることを提案します。装飾された関数は、パラメーターのリストでそのようなパラメーターを宣言する必要があります。 このメソッドの説明SO answer を使用して関数のパラメーター名を確認し、装飾された関数にそのようなパラメーターがない場合は例外をスローできます。
暗黙的なパラメータまたは必須のパラメータは、デコレータのdocstring(例ではcustom_decorator
)で説明する必要があります。返された関数(例ではwrapper
)で@wraps
デコレータを使用すると、__doc__
属性が関数f
からコピーされ、wrapper
。