2009-07-17 16 views
1

これはなぜ機能しませんか?どうすればそれを動作させることができますか?つまり、装飾された機能の中でどのようにアクセス可能にすることができますか?デコレータの機能を定義する

def decorate(f): 
    def new_f(): 
     def gu(): 
      pass 
     f() 
    return new_f 

@decorate 
def fu(): 
    gu() 

fu() 

何とか定義された関数の辞書にguを追加する必要がありますか?または、fを呼び出す前に、fのローカル名前空間にguを追加できますか?

答えて

0

あなたは古いものと同じコードを使用して新しい機能を作成してもでグローバルスコープを代入することができます

import new 

def with_bar(func): 
    def bar(x): 
     return x + 1 
    f_globals = func.func_globals.copy() 
    f_globals['bar'] = bar 
    return new.function(func.func_code, f_globals, 
         func.func_name, func.func_defaults, func.func_closure) 

@with_bar 
def foo(x): 
    return bar(x) 

print foo(5) # prints 6 

実際には、実際にこれを行うよりよい方法があります。パラメータとして関数を渡すことは1つの選択肢です。他のアプローチもあるかもしれませんが、問題の高い記述がなければ何が合うのかは分かりません。

1

GU飾り関数に対してローカルである new_f関数に対してローカルです。

1

gu()はnew_f()内でのみ定義されます。それを返すかnew_f()などにアンカーしない限り、new_f()の外部から参照することはできません

私はあなたのことを知りませんが、このスキームは非常に複雑です。たぶん、あまり複雑ではないソリューションを見つけることができます。

+0

この例は無意味ですが、私は問題を説明するための最も簡単な例を挙げようとしています。私は何をしたいのかがはっきりしているはずです。私はデコレータ定義の関数を装飾された関数で使用するために定義したいと思います。 – Alex

+0

@Alex:解決しようとしているより高いレベルの問題の説明を教えてください。たぶん誰かが全く違ったアプローチでよりクリーンなソリューションを提案するかもしれません。 – Ber

2

あなたはfuguを渡す必要がある場合は、パラメータで明示的にこれを実行する必要があります。原則として

​​3210
+0

fuの実際の定義に混乱を最小限に抑えるために、fの属性に関数guを追加する方法はありませんか?つまり、これはデコレータ、つまりAOPの目標です。懸念を分ける – Alex

+1

'gu 'が' fu'とは別のコンセプトであれば@Alexなぜ 'new_f'ではなく' fu'で呼び出すのですか?彼らが本当に別々の場合、彼らはお互いから見えないときにさらに便利です。明確にするためにあなたの質問にもっと詳細を入れてもらえますか? – lispmachine

0

デコレータを関数ではなくクラスにするのはなぜですか?私がpropertyの組み込みのヘルプを見たときに発見したように、明らかに可能です。 (以前は、クラスにデコレータを単に適用できると思っていましたが、デコレータ自体はクラスではないとは思っていませんでした)。guは、クラスまたは内部クラスのメソッドでなければなりません。 )

関連する問題