Вопрос

Ok, so the thing is let's say we have this piece of code:

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

The thing is I want every class that inherits the masterclass to get it's own id, awesome would be if it could be a plain counter, but any id is ok. I want the ID's to be embedded into the meta class so even if I call Slave1.id I would still get the number 1, as with every instance of the class as well.

Does anyone have any idea or solution to this issue?

Это было полезно?

Решение

This is a case for meta class. Meta classes are the classes which customize the construction of other classes.

# 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

Другие советы

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

Result:

(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>)

This is a solution I was after, if anyone has a better idea how to solve this, please by all means :)

You said incrementing is optional, yes?

If you can use a pseudo-random way to id the objects, you might be able to get away with just calling id(self) during the __init__ call.

>>> class A(object):
...     def __init__(self):
...             self.uid = id(self)
... 
>>> Stick = A()
>>> Stick.uid
4385894928
>>> Jupiter = A()
>>> Jupiter.uid
4385894672
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top