2009-07-02 75 views
4

我需要一個類,它的工作原理是這樣的:我需要保持它多少次實例化軌道Python類

>>> a=Foo() 
>>> b=Foo() 
>>> c=Foo() 
>>> c.i 
3 

這裏是我的嘗試:

class Foo(object): 
    i = 0 
    def __init__(self): 
     Foo.i += 1 

它可以根據需要,但我想知道是否有更多pythonic的方式來做到這一點。

+1

pythonic是什麼意思?如果它在python中工作...不是那個python ** ic **? – Victor 2009-07-02 00:14:09

+0

無需浪費時間實施其他任何方式 – fuentesjr 2009-07-02 00:16:29

+0

我把「pythonic」表示爲「在python中的成語」。像Java程序員一樣可以編寫Python,但不一定能展現出它的最佳品質或風格。 – duffymo 2009-07-02 00:21:04

回答

11

沒有。這很好。來自Python的禪宗:「簡單勝於複雜」。

這工作正常,並明確你在做什麼,不要複雜它。也許把它命名爲counter什麼的,但除pythonic之外你還是很好的。

5

濫用裝飾和元類。

def counting(cls): 
    class MetaClass(getattr(cls, '__class__', type)): 
     __counter = 0 
     def __new__(meta, name, bases, attrs): 
      old_init = attrs.get('__init__') 
      def __init__(*args, **kwargs): 
       MetaClass.__counter += 1 
       if old_init: return old_init(*args, **kwargs) 
      @classmethod 
      def get_counter(cls): 
       return MetaClass.__counter 
      new_attrs = dict(attrs) 
      new_attrs.update({'__init__': __init__, 'get_counter': get_counter}) 
      return super(MetaClass, meta).__new__(meta, name, bases, new_attrs) 
    return MetaClass(cls.__name__, cls.__bases__, cls.__dict__) 

@counting 
class Foo(object): 
    pass 

class Bar(Foo): 
    pass 

print Foo.get_counter() # ==> 0 
print Foo().get_counter() # ==> 1 
print Bar.get_counter() # ==> 1 
print Bar().get_counter() # ==> 2 
print Foo.get_counter() # ==> 2 
print Foo().get_counter() # ==> 3 

您可以通過頻繁使用雙下劃線名稱來判斷它是Pythonic。 (開玩笑,開玩笑...)

4

如果您想擔心線程安全問題(以便可以通過實例化Foo s的多個線程修改類變量),則上述答案是正確的。我問了這個關於線程安全性的問題here。總之,你會做這樣的事情:

from __future__ import with_statement # for python 2.5 

import threading 

class Foo(object): 
    lock = threading.Lock() 
    instance_count = 0 

    def __init__(self): 
    with Foo.lock: 
     Foo.instance_count += 1 

現在Foo可以從多個線程被實例化。

相關問題