有一个简单的类:
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
有一个简单的类:
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
要挂钩被调用的方法,您必须使用装饰器:
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如果您想为每个子类使用单独的计数器,请使用A.
这是一个简单的版本:如何在每次调用特定函数时增加一个类范围的计数器。该功能可以是__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。