私があなたのデザインを理解したので、あなたはすべて間違ったことをしている。
まず、アウターはクラスです。__call__
エドにはなりません。17行目は、空のOuter
オブジェクトを作成し、それに対して何もしません。Outer
オブジェクトを「呼び出す」場合は、__init__
メソッドを定義できます。または、Sheenaが提案するように__new__
、初期化されたオブジェクトは実際には必要ないため、を定義して初期化をインターセプトできます。
正直なところ、まだどのように機能するかを理解していない人は__call__
、まだこのようなトリッキーなものを構築しようとすべきではないと思います。しかし、あなたが主張するなら、読み続けてください。
この種のものをインスタンスではなくクラスに収集することは、非常に奇妙で、おそらく悪い設計です。クラス変数は事実上グローバルであり、それに伴うすべてのものがあることに注意してください。繰り返し使用しようとするとOuter
、または複数のスレッド/イベントハンドラー/グリーンレットなどから使用しようとすると、使用は互いに踏みにじられてしまいます。今は問題にならないだろうと思っていても、将来的には問題になる可能性があります。
インスタンスを作成し、Outer
そのメンバーをデコレータとして使用できます。例えば:
from outer_library import Outer
outer = Outer()
@outer.get("/")
…
しかし、それがはるかに優れているかどうかはわかりません。ここでの設計全体には、通常の関数を定義し、最後に関数を呼び出すだけのように見えますが、モジュールレベルでアクションを実行することが含まれているようです。あなたが自分自身を混乱させることができたという事実は、これがデザインをどれほど混乱させているかの証拠であるはずです。
ただし、それを実行したい場合は、Outer.__init__
メソッド内でクラスを定義し、それらをインスタンスメンバーに割り当てることをお勧めします。クラスはファーストクラスの値であり、他の値と同じように変数に割り当てることができます。次に、それらのクラスの__init__
(または__new__
)メソッドを使用して必要な作業を実行し、クラスに関数をシミュレートさせます。
これは、紛らわしいまたは誤解を招くように見える場合があります。ただし、実行しようとしていることの全体的なポイントは、メソッドのように見える方法でクラスを使用することであるため、問題には一種の混乱が内在していることを忘れないでください。ただし、必要に応じて、デコレータを関数として(この場合は)の通常のインスタンスメソッドとして記述できますOuter
。この部分ではなく、問題の別の部分を難しくするだけです。
このようなものを設計するためのより通常の方法はOuter
、人々がサブクラス化またはインスタンスを作成できる完全に通常のクラスを作成し、ハンドラーメソッドまたは関数をURLにアタッチするための明示的な非ファンシーな方法を提供することです。次に、それが機能したら、デコレータを使用してハンドラの登録を簡素化する方法を設計します。