我希望某些类的每个实例都具有唯一的整数标识符,这取决于我创建它们的顺序,从(比如说)0开始。在Java中,我可以执行此操作用一个静态类变量。我知道我可以用Python来模拟同样的行为,但是怎样才能做到这一点最“Python”呢?将ID分配给类的实例(Pythonic)
感谢
我希望某些类的每个实例都具有唯一的整数标识符,这取决于我创建它们的顺序,从(比如说)0开始。在Java中,我可以执行此操作用一个静态类变量。我知道我可以用Python来模拟同样的行为,但是怎样才能做到这一点最“Python”呢?将ID分配给类的实例(Pythonic)
感谢
下面的方法是比较Python的(我的Python化的主观判断 - 明确,但简洁):
class CounterExample(object):
instances_created = 0
def __init__(self):
CounterExample.instances_created += 1
def __del__(self):
""" If you want to track the current number of instances
you can add a hook in __del__. Otherwise use
__init__ and just count up.
"""
CounterExample.instances_created -= 1
如果你正面临大量的类,需要这种属性,你也可以考虑为它写一个元类。
元类的一个例子:http://www.youtube.com/watch?v=E_kZDvwofHY#t=0h56m10s。
我想一个很好的问题是什么时候以及如何创建它们?如果你只是在一个时间点创建了一定数量的数据,那么在for循环中使用一个范围。
class A:
def __init__ (self, id):
self.id = id
//do other stuff
class_list = []
for i in xrange(10):
class_list.append(A(i))
这将是一种pythonic方式。如果你在需要的时候创建它们,那么我认为唯一的办法就是在某个地方保留一个id静态变量。虽然我不确定你是如何制作它们的。
编辑:哦,另外,如果有疑问“导入这个”总能帮助你在正确的轨道搞清楚什么是“Python的”;)
的-myyn的回答是不错的 - 我想类对象是存放柜台的完美地方。但是,请注意,由于它不是线程安全的。 所以把它包在使用锁一类方法:
import threading
class CounterExample(object):
_next_id = 0
_id_lock = threading.RLock()
@classmethod
def _new_id(cls):
with cls._id_lock:
new_id = cls._next_id
cls._next_id += 1
return new_id
def __init__(self):
self.id = self._new_id()
def test():
def make_some(n=1000):
for i in range(n):
c = CounterExample()
print "Thread %s; %s has id %i" % (threading.current_thread(), c, c.id)
for i in range(10):
newthread = threading.Thread(target=make_some)
newthread.start()
test()
这将运行10个线程创建每个1000个实例。 如果您在没有锁定代码的情况下运行它,最终可能会得到低于9999的最后一个ID,从而显示竞争情况。
您可能还想在'__init__'的主体中放置'self.identifier = CounterExample.instances_created',因为mellort似乎希望每个对象都具有唯一的标识符。 (这反过来就意味着你不想在删除过程中减少'instances_created',因为这可能会导致对象被初始化为具有非唯一标识符的对象。) – JAB 2010-06-07 13:48:05
这很好,直到你试图用内部类,在此时它会失败,并且“CounterExample未定义”。你还需要做些什么来使其与内部课程一起工作? – Zxaos 2011-02-28 21:00:14