Violet
Violet

Reputation: 505

Make a hashable id for all subclasses of base class

For Caching/Persistence reasons I'm looking to get unique hashable address for an arbitrarily large tree of subclasses of a base class (which is never created itself). Here's what things look like at the moment:

OBJECT_CACHE = dict()

class Base(object):
    def __new__(cls, *args, **kwargs):
        # calculate class_addr here?
        obj = OBJECT_CACHE.get(class_addr)
        if obj is None:
            obj = super(Base, cls).__new__(cls, *args, **kwargs)
            OBJECT_CACHE[class_addr] = obj
        return obj

But I'm not sure what the best way to go about getting such an id would be. My concept is that it would look something like the following:

Base:          # no id
    F          # id = 'f'
    A:         # id = 'a'
        E      # id = 'a.e'
        B:     # id = 'a.b'
            C  # id = 'a.b.c'
            D  # id = 'a.b.d'

I thought about trying something with properties and super() but ideally the subclasses would only contain a single line like my_id = 'e'. Thanks in advance!

Upvotes: 2

Views: 189

Answers (1)

unutbu
unutbu

Reputation: 880547

What you are looking for is the cls.mro():

OBJECT_CACHE = dict()
class Base(object):
    def __new__(cls, *args, **kwargs):
        class_addr = cls.name()
        obj = OBJECT_CACHE.get(class_addr)
        if obj is None:
            obj = super(Base, cls).__new__(cls, *args, **kwargs)
            OBJECT_CACHE[class_addr] = obj
        return obj
    @classmethod
    def name(cls):
        names = [k.__name__.lower() for k in cls.mro() 
                if k != Base and issubclass(k, Base)]
        return '.'.join(names[::-1])


class F(Base): pass
class A(Base): pass
class E(A): pass
class B(A): pass
class C(B): pass
f = F()
a = A()
e = E()
b = B()
c = C()
print(OBJECT_CACHE.keys())

yields

['a', 'a.e', 'a.b.c', 'a.b', 'f']

Upvotes: 2

Related Questions