
最終段階:引数を処理する
あと少しです。デコレータコードの中心は用意できました。あとは、デコレータがデコレート
される関数の引数が何であっても処理できるようにするだけです。デコレータ作成手順の
4
を思
い出してください。
4
デコレータはデコレートされる関数のシグネチャを持つ
デコレータは返す関数がデコレートされる関数と同じ数と型の引数を取ることを
保証する必要があります。
デコレータを既存の関数に適用するときには、既存の関数の呼び出しをデコレータが返す関数
の呼び出しに置き換えます。前ページの解決策に示したように、デコレータ作成手順の
3
に従う
には、既存の関数のラップバージョンを返し、ラップバージョンの必要に応じて追加コードを実
装します。このラップバージョンが既存の関数をデコレートします。
しかし、これには問題があります。関数そのものをラップするだけでは十分ではありません。
デコレートされる関数の呼び出し特性も維持する必要があります。つまり、例えば既存の関数が
2
つの引数を取る場合、ラップ関数も
2
つの引数を取らなければいけません。求められる引数の
数が事前にわかれば、それに応じて対応できます。しかし残念ながら、デコレータはあらゆる既
存の関数に適
用でき、(まさしく文字どおり)あらゆる型の引数をいくつでも取る可能性があるの
で、事前に知ることはできません。
どうすればよいのでしょうか。「ジェネリクス型」にすると、
wrapper
関数が任意の数のあら
ゆる型の引数をサポートするようになります。
*args ...