最近、私はPythonで多くの仕事をしなければなりません。 現在の問題の1つを解決するために、decorator関数内で、装飾されたメソッドが別の装飾子によって装飾されているかどうかを確認する必要がありました。 残念ながら、標準の言語反映ツールではこれが許可されていません。 より正確には、たとえば標準ライブラリの検査モジュールを使用してこれを行うことができますが、私はこのアプローチが本当に好きではありませんでした。
カットの下では、問題を解決する独自の方法があり、一般的な使用に利用できる小さなライブラリが作成されます。
そのため、デコレータの特別なレジストリを作成して使用することが決定されました。 つまり デコレータとして使用する前に、このレジストリにデコレータ関数を登録します。 その後、レジストリAPIを使用して、メソッド、関数、およびモジュールで登録されたデコレータの使用を簡単に追跡できます。
ただし、留意すべきいくつかのルールがあります。 組み込みデコレータの登録は機能しません。 つまり、残念ながら、
@staticmethod
や
@classmethod
などのデコレータは追跡できません(誰かがこの問題の解決策を見つけることができれば、私はとても感謝します)。 そして最も重要なのは、デコレータ
を使用する前に登録
する必要がある
ことです。
実際、レジストリの仕組みは非常に単純です。 デコレータを登録することにより、実際には装飾されたソースデコレータを取得します。これは、元の機能に加えて、装飾されている関数の「__annotations__」属性に自身に関する情報も書き込みます。
関数(またはメソッド)が複数のデコレーターで装飾されている場合、それらを使用する前にすべてのデコレーターを登録することが重要であり、すべてのデコレーターが正しく考慮されます。 つまり、フォームの設計:
@decorator_one @decorator_two @decorator_three def some_function(): pass
正常に動作します。
「regd」ライブラリ(私が言ったように)は、Python 2.xとバージョン3.xの両方と互換性があります(プロジェクトで両方のブランチを使用するため、互換性がチェックされました)。
ソースは
Githubで入手できます。ライセンスはいつものようにMITなので、好きなようにできます。
ドキュメントは
こちらです。
PyPIから簡単にインストールできます:
$ pip install regd
以下は、機能に関するいくつかの言葉です。
1.デコレータの登録。
通常のデコレータとパラメータ化されたデコレータは、異なる方法を使用して登録する必要があります。
from regd import DecoratorRegistry as dreg
2.リフレクションAPI
API関数をより理解しやすくするために、最初に単純なデコレーターを作成して登録します。デコレーターは実際には何もしませんが、単に存在します。
from regd import DecoratorRegistry as dreg # def mydecorator( fn) : # - ... def wrapper( *args, **kwargs) # ... - ... return fn( *args, **kwargs) return wrapper # mydecorator = dreg.decorator( mydecorator)
覚えておいてください-デコレータ
を使用する前に登録する必要があり
ます 。
これで、登録後、通常どおりデコレーターを使用できます。
@mydecorator def myfunc() : pass
これで、いつでもコードのどこからでも、関数がデコレータによって装飾されているかどうかを確認できます。
print( dreg.is_decorated_with( myfunc, mydecorator))
より便利な方法:
all_decorated_module_functions( module, exclude_methods=False, exclude_functions=False)
-指定されたモジュールの登録済みデコレーターによって装飾されたクラスのすべての関数および/またはメソッドを取得できますmodule_functions_decorated_with( module, decorator, exclude_methods=False, exclude_functions=False)
-特定のモジュール内の特定のデコレーターによって装飾されたクラスのすべての関数および/またはメソッドを取得できますdecorated_methods( cls, decorator)
-指定されたデコレータによって装飾されたクラス/オブジェクトのすべてのメソッドを取得しますget_decorators( fn)
-指定された関数/メソッドのすべての既知のデコレータのリストを返しますget_real_function( fn)
-デコレータで装飾された元の関数へのリンクを返します(はい、元の関数にアクセスして、装飾をバイパスして実行することもできます)is_decorated_with( fn, decorator)
-指定is_decorated_with( fn, decorator)
れた関数が指定is_decorated_with( fn, decorator)
れたデコレータによってis_decorated_with( fn, decorator)
されているかどうかを確認します
誰かが重宝するか、役に立つと思います。 すべてのコメントと提案を歓迎します。