簡體   English   中英

如何創建特定於實例的 function 計數器?

[英]How to create instance specific function counter?

我想跟蹤 class 內的 function 計數,但是對於 class 的每個實例,該計數都不同。

我們可以在一個簡單的 function 上設置一個計數器:

def foo1():
    pass

foo1.count = 0
foo1.count +=1
print(foo1.count)

現在讓我們轉向 class 方法:

class A:
    def foo2(self):
        print('Hi')

我們也可以在這里設置計數器

A.foo2.count = 0
a = A()
b = A()

但這個計數不是特定於實例的

A.foo2.count += 1
print(a.foo2.count)
print(b.foo2.count)

無法為 INSTANCE 方法設置計數:

a.foo2.count += 1

如果我們使用__func__ ,它將等同於更改A.foo2.count

a.foo2.__func__.count += 1
print(b.foo2.count)
print(a.foo2.count)
print(A.foo2.count)

問題:如何使foo2.count INSTANCE 具體化? 所以ab可以有多個foo2.count值?

請注意:我問的是function屬性,而不是 class 屬性。

使用__init__方法:

class A:

    def __init__(self):
        self.count_foo2 = 0

    def foo2(self):
        print('Hi')
        self.count_foo2 += 1 


a = A()
b = A()

a.foo2()

print(a.count_foo2)
print(b.count_foo2)

Output:

Hi
1
0

那么可能是這個?

from collections import defaultdict


def foo1():
    print('Hi')
foo1.count = defaultdict(int)

class A:

    def foo2(self):
        foo1()
        foo1.count[self] += 1



a = A()
b = A()

a.foo2()
a.foo2()
b.foo2()

print(foo1.count)

output:

Hi
Hi
Hi
defaultdict(<class 'int'>, {<__main__.A object at 0x000001E59759ABE0>: 2, <__main__.A object at 0x000001E596AFCD30>: 1})

這是我的嘗試。 我不確定這是否完全是您想要的,因為在您的一條評論中您表示您特別想要 function 實例屬性(?)。 但是,這似乎與您描述的方式相同。 無論您希望發生這種行為的方法有多少,它都有工作的好處。

def fn_exec_count(base_fn):
    def new_fn(self, *args, **kwargs):
        fn_count_attr = 'fn_' + base_fn.__name__ + '_count'
        if not hasattr(self, fn_count_attr):
            setattr(self, fn_count_attr, 1)
        else:
            setattr(self, fn_count_attr, getattr(self, fn_count_attr) + 1)
        base_fn(self, *args, **kwargs)
    new_fn.__name__ = base_fn.__name__
    return new_fn

class A:
    @fn_exec_count
    def foo(self):
        fn_count_attr = 'fn_' + A.foo.__name__ + '_count' 
        print(f'Value of counter: {getattr(self, fn_count_attr, None)}')


a1 = A()
a1.foo()
a1.foo()
a2 = A()
a2.foo()
a1.foo()

輸出:

Value of counter: 1
Value of counter: 2
Value of counter: 1
Value of counter: 3

編輯:從 Julien 的回答中竊取使用 defaultdict 使得這稍微不那么冗長。

def fn_exec_count_dict(base_fn):
    def new_fn(self, *args, **kwargs):
        if not hasattr(self, 'fn_exec_count'):
            setattr(self, 'fn_exec_count', defaultdict(int))
        self.fn_exec_count[base_fn.__name__] += 1
        base_fn(self, *args, **kwargs)
    new_fn.__name__ = base_fn.__name__
    return new_fn

class A:
    @fn_exec_count_dict
    def foo(self):
        print(f'Value of counter: {self.fn_exec_count[A.foo.__name__]}')

# ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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