コンテクスト:
関数を装飾して、それらの統計を追跡できるようにしたいと思います。この投稿を参照として使用して、独自の呼び出し可能なデコレータオブジェクトを作成しようとしました。
これが私が最終的に得たものです:
def Stats(fn):
Class StatsObject(object):
def __init__(self, fn):
self.fn = fn
self.stats = {}
def __call__(self, obj, *args, **kwargs):
self.stats['times_called'] = self.stats.get('times_called', 0) + 1
return self.fn(obj, *args, **kwargs)
function = StatsObject(fn)
def wrapper(self, *args **kwargs):
return function(self, *args, **kwargs)
return wrapper
Class MockClass(object):
@Stats
def mock_fn(self, *args, **kwargs):
# do things
問題:
これは実際にはmock_fn関数を正しく呼び出しますが、ラッパー関数の外部にstatsオブジェクトへの参照がありません。つまり、私はできません:
mc = MockClass()
mc.mock_fn()
mc.mock_fn.stats
# HasNoAttribute Exception
次に、スコーピングの問題であることを認識して、次のコードを変更してみました。
から:
function = StatsObject(fn)
def wrapper(self, *args **kwargs):
return function(self, *args, **kwargs)
return wrapper
に:
function = StatsObject(fn)
return function
しかしもちろん、私は自己参照を失いました(selfはStatsObjectインスタンスになり、objは最初の引数になり、MockClassオブジェクトの自己参照は失われます)。
だから私は最初の問題が起こっている理由を理解していますが、2番目の問題は起こっていません。MockClassの自己参照をStatsObject__call__
関数に渡す方法はありますか?