문제

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