我需要的是这样的一类:
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
这里是我的尝试:
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
它的工作原理是必需的,但我不知道是否有一个更Python的方式来做到这一点。
我需要的是这样的一类:
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
这里是我的尝试:
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
它的工作原理是必需的,但我不知道是否有一个更Python的方式来做到这一点。
不。 这是相当不错的。
从Python中的禅:“简单比复杂好。”
这工作正常,是你在做什么明确的,不要把它复杂化。 也许它命名为counter
什么的,但除此之外,你就可以尽可能Python的去走。
装饰和元类的滥用。
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
你可以告诉它是由频繁使用双下划线的关键字的Python的。 (开玩笑,开玩笑...)
如果你要担心线程安全(以便类变量可以从被实例化多个线程修改Foo
,上面的回答是正确S)。 我问线程安全性这个问题在这里 。 总之,你会做这样的事情:
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
可以从多个线程被实例化。