我需要一个类,它的工作原理是这样的:我需要保持它多少次实例化轨道Python类
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
这里是我的尝试:
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
它可以根据需要,但我想知道是否有更多pythonic的方式来做到这一点。
我需要一个类,它的工作原理是这样的:我需要保持它多少次实例化轨道Python类
>>> a=Foo()
>>> b=Foo()
>>> c=Foo()
>>> c.i
3
这里是我的尝试:
class Foo(object):
i = 0
def __init__(self):
Foo.i += 1
它可以根据需要,但我想知道是否有更多pythonic的方式来做到这一点。
没有。这很好。来自Python的禅宗:“简单胜于复杂”。
这工作正常,并明确你在做什么,不要复杂它。也许把它命名为counter
什么的,但除pythonic之外你还是很好的。
滥用装饰和元类。
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。 (开玩笑,开玩笑...)
如果您想担心线程安全问题(以便可以通过实例化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
可以从多个线程被实例化。
pythonic是什么意思?如果它在python中工作...不是那个python ** ic **? – Victor 2009-07-02 00:14:09
无需浪费时间实施其他任何方式 – fuentesjr 2009-07-02 00:16:29
我把“pythonic”表示为“在python中的成语”。像Java程序员一样可以编写Python,但不一定能展现出它的最佳品质或风格。 – duffymo 2009-07-02 00:21:04