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