1

メソッドをオーバーライドせずに、シングルトン クラスから関数呼び出しをキャプチャしようとしています。

現在、私はこれをやっています:

class MyClass
    oldMethod = None

    def __init__(self):
        c = Class.Instance()
        self.oldMethod = c.Method #make a copy to the pointer of the original function
        c.Method = self.NewMethod #redirect it

    def NewMethod(self, x, a):
        self.oldMethod(x, a) #call the old function
        #My Stuff

「イベント」(メソッド呼び出し)とこのメソッド呼び出しのパラメーターをキャプチャしようとしています。これを「受動的に」キャプチャすると言う他の方法はありますか?ただ聞いてパラメータを取得してください。

注: シングルトン クラスのコードにはアクセスできません。

ありがとう

4

2 に答える 2

2

デバッグ中だけでなく、通常の操作中にメソッド呼び出しを傍受したいとおっしゃいました。このソリューションは、他の回答とは異なるアプローチです。元のオブジェクトへのすべての呼び出しに対する一種のラッパーとなる新しいオブジェクトを作成するプロキシ パターンアプローチを使用します。プロキシ レベルでは、必要に応じて呼び出しを記録および監視できます。

person.py

Personコードを示すために、personモジュールで呼び出されるサンプル クラスを作成しました。これは、コードを変更できないモジュールであると見なすことができます。

class Person(object):
    def __init__(self, name=None):
        self.name = name

    def greet(self, greeting='hello'):
        print '%s %s' % (greeting, self.name)

    def __repr__(self):
        return "Person(%r)" % self.name

たとえば .py

以下のコードでは、呼ばれるプロキシ オブジェクトを作成します。ProxyPersonこれを使用するPersonと、同じように動作し、greet メソッドへのすべての呼び出しをログに記録する動作が追加されます。soを使用していることに気付き*args, **kwargsました。Person は将来別の署名を持つ可能性がありますが、変更が加えられてもコードは壊れません。

import person

class ProxyPerson(person.Person):
    def greet(self, *args, **kwargs):
        print '--- greet() self=%r args=%r kwargs=%r' % (self, args, kwargs)
        super(ProxyPerson, self).greet(*args, **kwargs)

#person.Person = ProxyPerson #uncomment to monkey patch Person

jack, jill = person.Person('Jack'), ProxyPerson('Jill')
for p in jack, jill:
    p.greet()
    p.greet('hi')
    p.greet(greeting='why hello')

通常出力

以下の出力は、元の Person クラスが使用されている場合と、ProxyPerson が使用されている場合の実行の違いを示しています。例には、位置引数を使用しない呼び出し、位置引数を使用する呼び出し、最後にキーワード引数を使用する呼び出しも含まれています。

hello Jack
hi Jack
why hello Jack
--- greet() self=Person('Jill') args=() kwargs={}
hello Jill
--- greet() self=Person('Jill') args=('hi',) kwargs={}
hi Jill
--- greet() self=Person('Jill') args=() kwargs={'greeting': 'why hello'}
why hello Jill

モンキーパッチ出力

最後に、Monkey パッチ person.Personクラスを ProxyPerson を指すようにすることができます。のモンキー パッチ行をコメント アウトすることで、このアプローチを試すことができますexample.py。この場合の出力は次のようになります。

--- greet() self=Person('Jack') args=() kwargs={}
hello Jack
--- greet() self=Person('Jack') args=('hi',) kwargs={}
hi Jack
--- greet() self=Person('Jack') args=() kwargs={'greeting': 'why hello'}
why hello Jack
--- greet() self=Person('Jill') args=() kwargs={}
hello Jill
--- greet() self=Person('Jill') args=('hi',) kwargs={}
hi Jill
--- greet() self=Person('Jill') args=() kwargs={'greeting': 'why hello'}
why hello Jill

モンキー パッチの利点は、person.Person の将来のすべてのインスタンスが実際には、作成されたプロキシ オブジェクトのインスタンスになることです。Monkey パッチには、使用する前に留意すべき一連の問題があります。

于 2012-12-07T19:54:25.477 に答える
0

winpdbを使用できます。これは、Python用の非常に使いやすいグラフィカルデバッガーです。したがって、問題のPythonスクリプトを開き、監視したいクラスのメソッドにブレークポイントを設定します。その時点で一時停止し、変数の状態と、そのメソッドを呼び出すたびに何が表示されないかを示します。

于 2012-12-07T05:08:31.263 に答える