Reputation: 505
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
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