I would like to create a metaclass/descriptor in order to have a identifier attribute which counts through each instances. Furthermore I would like to have that the identifier attribute cannot be changed. This is what I have done so far:
class Identifier(object):
"""Iterator for Transformation Identification
"""
def __init__(self, current):
self.current = current
def __iter__(self):
return self
def __next__(self):
self.current += 1
return self.current
def __get__(self, instance, owner):
return self
def __set__(self, instance, value):
raise Exception('')
class InheritDecoratorsMixin:
_iter = Identifier(0)
def __init_subclass__(cls, *args, **kwargs):
setattr(cls, 'id', next(cls._iter))
super().__init_subclass__(*args, **kwargs)
Here we have an example:
class Test1(InheritDecoratorsMixin):
pass
class Test2(Test1):
pass
class Test3(Test1):
pass
class Test4(Test3):
pass
a = Test2()
print(a.id)
b = Test3()
print(b.id)
c = Test4()
print(c.id)
print(c.id)
c.id = 5
print(c.id)
The output is
2
3
4
4
5
This is fine except for the fact that the attribute can be changed. When I changed the code to:
class Identifier(object):
"""Iterator for Transformation Identification
"""
def __init__(self, current):
self.current = current
def __iter__(self):
return self
def __next__(self):
self.current += 1
return self
def __get__(self, instance, owner):
return self
def __set__(self, instance, value):
raise Exception('')
where the next returns 'self' which is basically the iterator then the value cannot be set to '5' but the attribute 'id' is not an integer anymore but an instance of the iterator class. Is there a way to combine both versions, where we both have an integer as id attribute as well as the restriction that the attribute cannot be changed?
Note: in the output there are different values for each subclass but it remains the same for each instance.
Thanks in advance for any help.