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