[英]How to count instance method calls with class decorator
目標是使用 class 裝飾器計算實例方法調用。 我選擇了 class 裝飾器,因為想為每個裝飾實例方法分別存儲字段 call_count 。 function 裝飾器無法解決此問題,因為開發人員應手動將字段 call_count 添加到具有裝飾方法的 class 或添加到裝飾器 function 屬性字段 call_count。 第一種情況不遵循 OOP 范式,並且還有額外的工作。 在第二種情況下,function 屬性保留所有修飾實例方法的計數(將實例數量乘以修飾方法的數量)。 結果我想得到這樣的呼叫計數: instance_name.method_name.call_count
。 我在這里研究了類似的問題並嘗試了所有這些問題,但無法解決問題。 函數的裝飾器沒有幫助,因為裝飾的方法沒有收到 class 實例:
class Wrapper(object):
def __init__(self, func):
self.call_count = 0
self.func = func
def __call__(self, *args, **kwargs):
self.call_count += 1
return self.func(*args, **kwargs)
class SomeBase:
def __init__(self):
self._model = " World"
@Wrapper
async def create(self, arg_1, arg_2):
return arg_1 + self._model + arg_2
async def test_wrapper():
base = SomeBase()
result = await base.create("hello", "!")
await base.create("hello", "!")
assert result == "hello World!"
assert base.create.call_count == 2
我得到一個錯誤:
test_call_count.py::test_wrapper FAILED
utils/tests/test_call_count.py:95 (test_wrapper)
async def test_wrapper():
base = SomeBase()
> result = await base.create("hello", "!")
test_call_count.py:98:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <utils.tests.test_call_count.Wrapper object at 0x7f8c10f8b310>
args = ('hello', '!'), kwargs = {}
def __call__(self, *args, **kwargs):
self.call_count += 1
> return self.func(*args, **kwargs)
E TypeError: create() missing 1 required positional argument: 'arg_2'
test_call_count.py:84: TypeError
如何解決這個問題呢?
這可以通過重寫__get__
方法來實現,該方法的第一個參數包含實際 class 的實例,其方法已被修飾。 如果保存此參數,則可以在__call__
方法中重用它,將其作為真實方法的第一個參數傳遞:
class Wrapper(object):
def __init__(self, func):
self.call_count = 0
self.decorated_instance = None
self.func = func
def __call__(self, *args, **kwargs):
self.call_count += 1
return self.func(self.decorated_instance, *args, **kwargs)
def __get__(self, obj, objtype):
self.decorated_instance = obj
return self
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.