malving
malving

Reputation: 33

How to create an attribute that will be incremented each time the class is being inherited. Python

I'm looking for an answer how to increment superclass id attribute each time subclass(not object) is being created.

class Item:

    def __init__(self, id, name, level, rarity):
        self.id = id
        # attributes


class Weapon(Item):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # attributes


class Armor(Item):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class Wooden_sword(Weapon):
    def __init__(self):
        super().__init__(id=0, # **attributes=value)


class Wooden_armor(Armor):
    def __init__(self):
        super().__init__(id=1, # **attributes=value)


class Wooden_bow(Weapon):
    def __init__(self):
        super().__init__(id=2, # **attributes=value)

But I want it to be automatic, because I have a function which searches an object by it's id.

Can this be done using database?

Upvotes: 0

Views: 151

Answers (1)

quamrana
quamrana

Reputation: 39354

This is one idea I had. You can create a meta class which can be used to intercept the creation of the class itself. Here, and this is my simplistic attempt, you can see whether the class name has an '_' in it, eg. Wooden_bow and for these classes only assign an id member to the class itself.

You may want a different strategy of assigning ids.

#soClassId
#You need to get the subclasses to increment the id:

class MyMeta(type):
    id = 0
    def __new__(cls, classname, supers, classdict):
        print(f"meta: creating {classname} {supers}")
        ret = type.__new__(cls, classname, supers, classdict)
        if '_' in classname:
            i = MyMeta.id
            MyMeta.id = i + 1
            ret.id = i
        return ret

    __repr__ = lambda c: c.__name__
    
class Item(metaclass=MyMeta):
    def __init__(self, name, level, rarity):
        print(f'{self.__class__.__name__} {self.id}')


class Weapon(Item):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class Armor(Item):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class Wooden_sword(Weapon):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class Wooden_armor(Armor):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

#name=0, level=0, rarity=0
s = Wooden_sword(name=0, level=0, rarity=0)
a = Wooden_armor(name=0, level=0, rarity=0)

a = Wooden_armor(name=0, level=0, rarity=0)
s = Wooden_sword(name=0, level=0, rarity=0)

Output:

meta: creating Item ()
meta: creating Weapon (Item,)
meta: creating Armor (Item,)
meta: creating Wooden_sword (Weapon,)
meta: creating Wooden_armor (Armor,)
Wooden_sword 0
Wooden_armor 1
Wooden_armor 1
Wooden_sword 0

The above shows a diagnostic of when the classes themselves are created, and then when the instances are created that the id relates to the class and not the instance.

Upvotes: 1

Related Questions