カットの下では、問題を解決する独自の方法があり、一般的な使用に利用できる小さなライブラリが作成されます。
そのため、デコレータの特別なレジストリを作成して使用することが決定されました。 つまり デコレータとして使用する前に、このレジストリにデコレータ関数を登録します。 その後、レジストリ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 # "" simple_decorator = dreg.decorator( mydecorator) # "" param_decorator = dreg.parametrized_decorator( param_decorator)
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)
されているかどうかを確認します
誰かが重宝するか、役に立つと思います。 すべてのコメントと提案を歓迎します。