大体次のようなものがあります。基本的には、インスタンス メソッドの定義で使用されるデコレータからインスタンス メソッドのクラスにアクセスする必要があります。
def decorator(view):
# do something that requires view's class
print view.im_class
return view
class ModelA(object):
@decorator
def a_method(self):
# do some stuff
pass
そのままのコードは次のようになります:
AttributeError: 'function' オブジェクトに属性 'im_class' がありません
同様の質問/回答を見つけました -Pythonデコレータは関数がクラスに属していることを忘れさせますそしてPythonデコレータでクラスを取得する- しかし、これらは、最初のパラメータを取得して実行時にインスタンスを取得する回避策に依存しています。私の場合は、クラスから収集した情報に基づいてメソッドを呼び出すため、呼び出しが来るのを待つことはできません。
ベストアンサー1
Python 2.6 以降を使用している場合は、次のようなクラス デコレータを使用できます (警告: 未テストのコード)。
def class_decorator(cls):
for name, method in cls.__dict__.iteritems():
if hasattr(method, "use_class"):
# do something with the method and class
print name, cls
return cls
def method_decorator(view):
# mark the method as something that requires view's class
view.use_class = True
return view
@class_decorator
class ModelA(object):
@method_decorator
def a_method(self):
# do some stuff
pass
メソッド デコレータは、「use_class」属性を追加することで、メソッドを興味のあるものとしてマークします。関数とメソッドもオブジェクトであるため、追加のメタデータを添付できます。
クラスが作成されると、クラス デコレータはすべてのメソッドを調べ、マークされたメソッドに対して必要な処理を実行します。
すべてのメソッドに影響を与えたい場合は、メソッド デコレータを省略し、クラス デコレータのみを使用します。