繁体   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