2017-10-02 7 views
0

私は、次の操作を実行しているよ:Python - そのクラス内のメソッドのデコレータの引数としてクラスを渡しますか?

class A(object): 
    def first_method(self): 
     print "I'm the first method!"  

    @some_decorator(A.first_method) 
    def second_method(self): 
     print "I'm the second method!" 

しかし、私はAがデコレータが解析された時点で自身の中に定義されていない問題に実行していますよ。デコレータにAを参照する方法はありますか?代わりに、デコレータを渡しただけの場合、バインドされたメソッドfirst_methodは、それを回復することが可能ですfirst_methodAに属していますか?あなたは(@なし)古典的な機能として、あなたのデコレータを使用することができます

+0

私はこの小さなブログの記事を考えます有用であるかもしれません:http://scottlobdell.me/2015/04/decorators-arguments-python/ – freddiev4

+0

@ FreddieV4、私は引数を使ってデコレータを作成する方法を知っています。この問題は、前述したように、「A」はそれ自体では定義されていないことである。 'A'の中から関数の外に' first_method'を参照すると、 'A.first_method'ではなく' unbound'メソッド 'first_method'が返されます。 –

答えて

1

、あなただけ@some_decorator(first_method)を言うことができ、それが動作しますが、すべてのメソッドは、クラスでの通常の機能であるためコンテナとして。

Python 2では、バインドされたバインドされていない、インスタンス、クラス、および静的メソッドの複雑なシステムがあります。このため、クラス定義の内側(完全に形成されている場合はクラスまで)にfirst_methodにアクセスすることはできません。

少し問題を回避するには、二つのクラスにそのクラスを分割するために、次のようになります。

class BaseA(object): 
    def first_method(self): 
     print "I'm the first method!"  

class A(BaseA): 
    @some_decorator(BaseA.first_method) 
    def second_method(self): 
     print "I'm the second method!" 

ないすべてのケースのための最善の解決策が、動作します。また


、覚えておいて、それはここで宣言されたように両方のケース(PY2 & PY3を)に、デコレータはfirst_methodを参照すること。任意の子孫クラスがメソッドを再定義すると、新しいメソッドはデコレータで使用されません。親のものだけが使用されます。

恐らく、first_methodを参照しないでください。代わりに、ちょうどself/clsデコレータのラッパーの最初の位置引数を受け入れ、そこself.first_method/cls.first_methodを使用します。

import functools 

def some_decorator(fn): 
    @functools.wraps(fn) 
    def wrapper(self, *args, **kwargs): 
     first_method = self.first_method 
     first_method() 
     return fn(self, *args, **kwargs) 
    return wrapper 

class A(object): 
    def first_method(self): 
     print "I'm the first method of A!"  

    @some_decorator 
    def second_method(self): 
     print "I'm the second method!" 


class B(A): 
    def first_method(self): 
     print "I'm the first method of B!"  


A().second_method() 
# I'm the first method of A! 
# I'm the second method! 

B().second_method() 
# I'm the first method of B! 
# I'm the second method! 

あなたはその方法は、設定したい場合:

def some_decorator(method_name): 
    def decorator(fn): 
     @functools.wraps(fn) 
     def wrapper(self, *args, **kwargs): 
      first_method = getattr(self, method_name) 
      first_method() 
      return fn(self, *args, **kwargs) 
     return wrapper 
    return decorator 


class A(object): 
    def first_method(self): 
     print "I'm the first method of A!"  

    @some_decorator('first_method') 
    def second_method(self): 
     print "I'm the second method!" 

class B(A): 
    def first_method(self): 
     print "I'm the first method of B!"  
+0

その最後のビットが答えのメイトです!ラッパーが自分自身を受け入れると、基本クラスがキャプチャされます!素晴らしいもの。ありがとう。 –

0

ます:python 3では

def some_decorator(arg): 
    # ... 
    pass 


class A(object): 
    def first_method(self): 
     print("I'm the first method!") 

    def second_method(self): 
     print("I'm the second method!") 


A.second_method = some_decorator(A.first_method)(A.second_method) 
関連する問題