2016-07-12 1 views
4

モジュールスコープで定義された関数barを呼び出すメソッドを持つFooクラスのモジュールがある場合、モジュールに変更を加えずに別の関数にbarを代入する方法があります?既存のメソッドの関数呼び出しを置換する方法

class Foo(object): 
    def run(self): 
     bar() 

def bar(): 
    return True 

Iは、私はFooクラスを変更することなくbar()する機能baz()を代入したい対象のFooのインスタンスを有します。

+0

あなたは他のインスタンスに影響を与えることなく、1つだけのインスタンスのために変更したいのですか? –

+0

私のアプリケーションはいずれの方法でも動作します。私は必要に応じてクラスまたは各インスタンスを変更することができます。 – Mike

答えて

9

のは、あなたのモジュールがdeadbeefと呼ばれていると仮定しましょう、そしてあなたは猿の実行時にパッチFoo、とは

import deadbeef 
deadbeef.bar = baz 
… 
+0

モジュール名のUpvote。 –

+0

@ScottHunterありがとう:) –

+3

正解のためのUpvote。モジュール名を混乱させる。 –

4

上書きすることができますそして、あなたが行うことができ、この

import deadbeef 
… 
foo_instance = deadbeef.Foo() 

のようにそれを使用しています方法run。例えば

fooはあなたが行うことができますFooのインスタンスである場合:

def run(obj): 
    baz() 

foo.run = run 

あなたはそれがbazを起動しますfoo.run呼び出して次の時間。

はもっとここにhttp://blog.tryolabs.com/2013/07/05/run-time-method-patching-python/

+0

クラスメソッドの代わりにインスタンス変数を設定するので、オブジェクトを最初の引数として取らないので、 'foo.run = baz'だけで十分です。また、これは 'Foo'の全てのインスタンスではなく、一つのインスタンスだけを変更しますが、マジックメソッドでは機能しません。 (OPには当てはまらないかもしれません) –

+0

メソッド 'foo.run'を置き換えるのはかなり簡単ですが、置き換えたいのはメソッド全体を再実装することなく' foo.run'内で呼び出される関数です。私の例の 'bar'関数はクラスが宣言されたときに' foo.run'に束縛されていると信じています。 'bar = baz'を置き換えるだけで' foo.run'は変更されません。 – Mike

0

私は最近、似たような頼み、(あなたのバズとバーは、メソッドのように見えるいけないので)staticmethodが答えだったを参照してください。基本的には、Strategy Patternのようなものを実行し、run()とは別の関数を呼び出したいとします。

def bar(): 
    print "I am bar()" 
    return True 

def baz(): 
    print "I am baz()" 
    return True 

class Foo(object): 

    # default to running bar. 
    torun = staticmethod(bar) 

    def run(self): 
     self.torun() 

foo = Foo() 

foo.run() 

foo2 = Foo() 
foo2.torun = baz 

foo2.run() 

出力:

I am bar() 
I am baz() 

あなたが別のモジュールで定義された関数を含む、あなたのfooインスタンスに望んでいたものは何でもほとんどを割り当てることができます。そして実行すると、より柔軟に* argsと** kwdsを取ることができます。

関連する問題