もう少し反射を追加:デコレータ

最近、私は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 #  ""  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)) 


より便利な方法:



誰かが重宝するか、役に立つと思います。 すべてのコメントと提案を歓迎します。

Source: https://habr.com/ru/post/J178017/


All Articles