So, I have a metaclass that caches instances of objects it's classes create, to avoid duplicating instances:
class _CachingMeta(type):
    __cache__ = {}
    def __init__(self, n, b, d):
        # ... Do stuff...
        return super(_CachingMeta, self).__init__(n, b, d)
    def __call__(cls, *a, **kw):
        # Simplified caching key
        key = frozenset((cls, frozenset(a), frozenset(kw.items())))
        if key not in _CachingMeta.__cache__:
            _CachingMeta.__cache__[key] = super(_CachingMeta, cls).__call__(*a, **kw)
        return _CachingMeta.__cache__[key]
class StaticClass(object):
    __metaclass__ = _CachingMeta
    def __init__(self, *a, **kw):
        pass
inst1 = StaticClass('arg1')
inst2 = StaticClass('arg1')
inst3 = StaticClass('arg3')
print (inst1)
print (inst2)
print (inst3)
prints:
<__main__.StaticClass object at 0x7f7ad8690c90>
<__main__.StaticClass object at 0x7f7ad8690c90>
<__main__.StaticClass object at 0x7f7ad8690d10>
I would like to also dynamically create classes and I would like the classes and the instances of those classes to be cached, and I thought I could create a metaclass that both extends _CachingMeta and uses it as a __metaclass__, but this seems to fail, and I can't wrap my head around why, e.g.:
class _ClassCachingMeta(_CachingMeta):
    '''
    Purpose: to cache generated classes and their instances
    '''
    __metaclass__ = _CachingMeta
def create_class(param):
    class DynamicClass(object):
        __metaclass__ = _ClassCachingMeta # A meta class that caches both  the classes it creates and their instances
        __param__ = param
    return DynamicClass
prints:
Traceback (most recent call last):
  File "../test2.py", line 29, in <module>
    class _ClassCachingMeta(_CachingMeta):
  File "../test2.py", line 7, in __init__
    return super(_CachingMeta, self).__init__(n, b, d)
TypeError: Error when calling the metaclass bases
    descriptor '__init__' requires a 'type' object but received a 'str'
It seems like _ClassCachingMeta doesn't get a bound __init__ method before the it's __metaclass__.__init__ is called (which I guess are the same method/function?) (e.g.):
class _CachingMeta(type):
    __cache__ = {}
    def __init__(self, n, b, d):
        print ("initilizing {0}".format(self))
        print (super(_CachingMeta, self).__init__)
        return super(_CachingMeta, self).__init__(n, b, d)
    def __call__(cls, *a, **kw):
        # Simplified caching key
        key = frozenset((cls, frozenset(a), frozenset(kw.items())))
        if key not in _CachingMeta.__cache__:
            _CachingMeta.__cache__[key] = super(_CachingMeta, cls).__call__(*a, **kw)
        return _CachingMeta.__cache__[key]
class StaticClass(object):
    __metaclass__ = _CachingMeta
    def __init__(self, *a, **kw):
        pass
class _ClassCachingMeta(_CachingMeta):
    '''
    Purpose: to cache generated classes and their instances
    '''
    __metaclass__ = _CachingMeta
def create_class(param):
    class DynamicClass(object):
        __metaclass__ = _ClassCachingMeta # Cache the class and it's instances
        __param__ = param
    return DynamicClass
gives:
initilizing <class '__main__.StaticClass'>
<method-wrapper '__init__' of _CachingMeta object at 0xc44cf0>
initilizing <class '__main__._ClassCachingMeta'>
<slot wrapper '__init__' of 'type' objects>
Traceback (most recent call last):
  File "../test2.py", line 32, in <module>
    class _ClassCachingMeta(_CachingMeta):
  File "../test2.py", line 9, in __init__
    return super(_CachingMeta, self).__init__(n, b, d)
TypeError: Error when calling the metaclass bases
    descriptor '__init__' requires a 'type' object but received a 'str'
Is there a straightforward way to implement this, or do I need to go with a different approach? Also, if anyone can help me understand why a class can't extend it's own __metaclass__ that would be awesome.
 
    