为每个继承类分配标识符

时间:2014-04-17 10:31:52

标签: python metaprogramming

好的,那就是说我们有这段代码:

class Master(object):
    id = SomePythonMagic()


class Slave1(master):
    pass

class Slave2(master):
    pass

class Slave3(master):
    pass



slave1 = Slave1()
print slave1.id
>> 1
slave2 = Slave2()
print slave2.id
>> 2
slave3 = Slave3()
print slave3.id
>> 3
slave4 = Slave1()
print slave4.id
>> 1

问题是我希望每个继承masterclass的类都能获得它自己的id,如果它可以是一个普通的计数器,那就太棒了,但是任何id都可以。 我希望ID被嵌入到元类中,所以即使我调用Slave1.id,我仍然会得到数字1,就像每个类的实例一样。

有没有人对这个问题有任何想法或解决方案?

3 个答案:

答案 0 :(得分:1)

这是meta class的案例。元类是定制其他类构造的类。

# Define the metaclass
class metacls(type):
    counter = 0
    def __new__(meta_class, name, bases, attributes):
        attributes['id'] = metacls.counter
        metacls.counter += 1
        return type.__new__(meta_class, name, bases, attributes)

# Set the metaclass    
class Master(object): __metaclass__ = metacls

class Slave1(Master): pass
class Slave2(Master): pass
class Slave3(Master): pass

print Slave1.id, Slave1().id
# 1 1
print Slave2.id, Slave2().id
# 2 2
print Slave3.id, Slave3().id
# 3 3

答案 1 :(得分:0)

class ClassIncrementor:
    def __init__(self):
        self.id = 0
    def __call__(self, cls):
        self.id += 1
        cls.id = self.id
        return cls
taskIncrementor = ClassIncrementor()


@taskIncrementor
class Slave1(object):
    pass

@taskIncrementor
class Slave2(object):
    pass

@taskIncrementor
class Slave3(object):
    pass

结果:

(1, <__main__.Slave2 object at 0x021C1DF0>)
(0, <__main__.Slave1 object at 0x021CA130>)
(2, <__main__.Slave3 object at 0x021CA290>)
(2, <__main__.Slave3 object at 0x021CA290>)
(2, <__main__.Slave3 object at 0x021CA290>)

这是我追求的解决方案,如果有人有更好的想法如何解决这个问题,请务必:)

答案 2 :(得分:0)

你说增量是可选的,是吗?

如果您可以使用伪随机方式来识别对象,则可以在id(self)来电期间调用__init__,从而逃脱。

>>> class A(object):
...     def __init__(self):
...             self.uid = id(self)
... 
>>> Stick = A()
>>> Stick.uid
4385894928
>>> Jupiter = A()
>>> Jupiter.uid
4385894672