2013-06-21 17 views
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 
+0

使用裝飾:http://www.artima.com/weblogs/viewpost.jsp?thread=240808 –

+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,如果你想使用每個子類的A一個獨立的計數器。

+0

不幸的是 - 對問題的更新使得這個問題比原始問題隱含得多:( –

+0

感謝不同的決定。 –

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

相關問題