2009-07-02 77 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可以从多个线程被实例化。

相关问题