在调用实例时如何增加类的计数器属性?

时间:2013-06-21 11:08:30

标签: python

有简单的课程:

class A(object):

    __COUNTER = 0

    def do_something_1(self):
        ...

    def do_something_2(self):
        ...

    def do_something_N(self):
        ...

是否有可以通过调用方法增加self.__COUNTER而不是将其写入每个函数的决定?

我想要的东西是:

a = A()
# COUNTER = 1

b = A()
# COUNTER = 2

c = A()
# COUNTER = 3

2 个答案:

答案 0 :(得分:6)

要挂钩被调用的方法,你必须使用装饰器:

def increment_counter(method):
    def wrapper(self, *args, **kw):
        self._COUNTER += 1
        return method(self, *args, **kw)
    return wrapper

并将其应用于班级中的每个方法:

class A(object):
    _COUNTER = 0

    @increment_counter
    def do_something_1(self):
        ...

    @increment_counter
    def do_something_2(self):
        ...

    @increment_counter
    def do_something_N(self):
        ...

请注意,我将计数器重命名为使用一个下划线,以避免必须找出损坏的名称。

如果你必须__COUNTER工作(所以使用双下划线),你可以通过传入类的名称来做到这一点:

def increment_counter(classname):
    counter_attribute = '_{}__COUNTER'.format(classname)
    def increment_counter_decorator(method):
        def wrapper(self, *args, **kw):
            setattr(self, counter_attribute, getattr(self, counter_attribute) + 1)
            return method(self, *args, **kw)
        return wrapper

然后用以下方法装饰方法:

@increment_counter('A')
def do_something_1(self):
    ...

如果您想要创建一个计数器每个实例,只需添加到类上的计数器

class A(object):
    _COUNTER = 0

    def __init__(self):
        A._COUNTER += 1
如果您想为type(self)._COUNTER的每个子类使用单独的计数器,请使用{{1>}。

答案 1 :(得分:3)

这是简单版本:如何在每次调用特定函数时递增类范围的计数器。该函数可以是__init__,它涵盖了您的具体问题。

class cls(object):
    counter = 0

    def __init__(self):
        self.__class__.counter += 1
        print self.__class__.counter

a = cls()  # Prints 1
b = cls()  # Prints 2

正如您所看到的,诀窍是增加self.__class__.counter,而不是self.counter。你可以在任何成员函数中做到这一点。

但是不要使用以双下划线开头的名称,因为它们对python有特殊意义(当然,除非你知道并想要特殊含义)。如果要将计数器标记为私有,请使用单个下划线:_counter