[英]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 具體化? 所以a
和b
可以有多個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.