2012-02-29 17 views
3

デコレータのデコレータのようなものに頼らないで、関数に適用されたデコレータのリストを取得する方法はありますか?関数に適用されたデコレータのリストを取得できますか?

+0

ここでは、この質問には多少異なる(しかし容易に適応可能な)形式でこの質問にほとんど答えました:http://stackoverflow.com/questions/5910703/howto-get-all-methods-of-a-python -class-with-given-decoratorデコレータをデコレートすることは、ソースコードのハック、C-pythonハックなどのハックアップよりも少なくなります。私の謙虚な意見では、「デコレータをデコレートする」はまったくハックしておらず、一般的なテクニックです。(また、この質問はリンクされた質問のサブセットであると考えられるかもしれません。なぜなら、メソッドは主に関数であるからですが、より多くのトリックを適用することができるからです)。 – ninjagecko

答えて

3

まず、すべてのデコレータがラッパー関数を返すわけではないので、デコレータは単に既存の関数を変更するだけです(おそらく属性を設定します)。Pythonはどのような関数にすべての属性が当てはまるのかを記録しません。第二に、ガーベジコレクタに、装飾された関数への参照を保持するクロージャと、クロージャを持つ関数に問い合わせることはおそらく可能ですが、クロージャ内の別の関数への参照を保持する関数はデコレータによって適用されるラッパーではありません。引き続き議論を行うデコレータの問題があります。実際の装飾機能に到達する前に、内部関数の余分な層があります。最後に、すべてのデコレータが関数ではなく、すべての装飾オブジェクトが関数ではありません。

要するに、いくつかの時間を近似することは可能かもしれませんが、動作しても、CPythonでしか動作しない大きなハックになります。シンプルで文書化された方法はありません。

+0

+1は私よりも想像力豊かなハッキリです。結局のところ、半機能的なソリューションでさえも、「デコレータを飾る」よりもハックになることがあります。それは、さようなら、本当にすべてがハッキングしているわけではありません。 – senderle

1

デコレータには、関数を置き換えたり、関数をラップしたり、必要なものを返すためのオプションがあるので、これは不可能だと思います。関数に "適用"されているわけではありません。

3

私は間違っていることを証明するために、何かがいつもpython標準ライブラリの深みから泡立つように見えるので、このような回答を投稿するのは不安です。しかし、私は本当に答えはノーだと確信しています。

デコレータは関数そのものに過ぎません。@fooは、func = foo(func)の文法的な砂糖ですから、まだあなたに与えられていない機能は何も追加していません。それほど多くはありません。

それはあなたが、func_dictでつつくことができfunc_globalsfunc_defaultsfunc_closureというように、といくつかの推測を作るかもしれないことは可能ですが、に行動を手でコーディング関与しない良い一般的な解決策があることをそうですデコレータ。あるいは、あなたが言うように、デコレータを飾ることによって。

0

他の答えとして、デコレータは関数をラップすることはできませんでしたが、変更するだけでした。その場合、デコレータはそれらを見つけることができませんでした。

しかし、ラッパーデコレータの場合、Pythonのデバッグフックを使うことができます。簡単ではなく、クリーンではありませんが、デバッグフックをそれぞれ呼び出す関数を入力して、装飾された関数を呼び出す - 新しい関数に入力したフックが呼び出されるたびに、それがあなたの "最終"関数かどうかを調べるためにイントロスペクションを使います(あなたのデコレータがfunctools .wrapそれ自身で、あなたの望む関数はオリジナルの__name__属性を保持する唯一のものです。それ以外の場合はもっと厄介です) - sys.settracebdbモジュールのドキュメントを参照して、何かを考え出してください。

しかし、これを考えるとき、デコレータを飾るdoeはもうハックを見ないのですか?

関連する問題