2012-07-31 1 views
17

私はその機能に鈍い繰り返しパターンのクラスを持っており、このパターンをデコレータに変えたいと思っていました。しかし、デコレータは現在のインスタンスのいくつかの属性にアクセスする必要があるので、このクラスのメソッドに変換したいと思っています。私はそれにいくつか問題があります。メソッドを同じクラスの別のメソッドのデコレータにすることはできますか?

だから、これは私が欲しいもののようになります。

class DullRepetitiveClass: 
    def __init__(self, nicevariable): 
     self.nicevariable = nicevariable 

    def mydecorator(self, myfunction): 
     def call(*args, **kwargs): 
      print "Hi! The value of nicevariable is %s"%(self.nicevariable,) 
      return myfunction(*args, **kwargs) 
     return call 

    @mydecorator   #Here, comment (1) below. 
    def somemethod(self, x): 
     return x + 1 

(1)ここで問題があります。私はDullRepetitiveClass.mydecoratorメソッドを使用してsomemethodメソッドを飾りたいです。しかし、現在のインスタンスのメソッドをデコレータとして使用する方法はわかりません。

これを行う簡単な方法はありますか?

編集:OK、答えはかなり明白です。 Svenがそれを下に置くと、デコレータ自体がメソッドを変換するだけです。メソッド自体は、インスタンスに関するすべてのものを処理する必要があります。

def mydecorator(method): 
    def call(self, *args, **kwargs): 
     print "Hi! The value of nicevariable is %s"%(self.nicevariable,) 
     return method(self, *args, **kwargs) 
    return call 


class DullRepetitiveClass: 
    def __init__(self, nicevariable): 
     self.nicevariable = nicevariable 

    @mydecorator    
    def somemethod(self, x): 
     return x + 1 
+1

インデントを修正してください。また、コードにはクラスメソッドが含まれていないことに注意してください。 –

+0

'somemethod'をデコレートするので、' self'以外の*インスタンスを 'mydecorator'に渡す方法を尋ねていますか? – kojiro

+0

vimからコピーしてブラウザに貼り付けると、時には苦痛になることがあります... –

答えて

11

デコレータは、飾り付ける関数またはメソッドの1つだけを取得します。 selfというパラメータをインスタンスに渡すことはありません。デコレータが呼び出された時点では、クラスも作成されていません。インスタンスは装飾された関数の最初の引数として渡されるので、call()のパラメータリストに最初のパラメータとしてselfを含める必要があります。

デコレータをクラススコープに含める必要はありません。あなたはこれを行うことができますが、モジュールスコープでも同じことができます。

+0

くそー、それはとても明らかです。デコレータは単にメソッドを受け取り、変更されたメソッドを返します。方法はインスタンスを扱わなければならない人です...。とても明らかです。 –

+0

デコレータがクラスメンバを使用する必要がある場合はどうなりますか?それとも、それはちょうど良いアイデア/パターンですか? – aaronlevin

+0

@weirdcanada:デコレータが呼び出された時点でクラスが作成されていないため、通常の方法でそのメンバにアクセスすることはできません。これを回避するためにいくつかのハックを行うことができます(デコレータのパラメータとして 'locals()を渡すようなもの)がありますが、それはかなり明白ではありません。 –

関連する問題