簡體   English   中英

如何使用 class 裝飾器計算實例方法調用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM