Extended class can't be pickled

Viewed 77

I have designed a way to inherit from a class programmatically, so basically extending a class. It works pretty nicely. However, I need to pickle the class, and this is not possible as the extended class is defined within a function.

Here is a toy example for the extended class:

import pickle

class A():
    pass

def extend_class(base_class):
    class B(base_class):
        def hello(self):
            print('Yo!')

    return B

extended_class = extend_class(A)

b = extended_class()
b.hello()

However if I do

pickle.dump(b, open('extended_class.pickle', 'w'))

this returns:

AttributeError: Can't pickle local object 'extend_class.<locals>.B'

Any workaround? I don't necessarely need to use my way to extend a class. Any other way would be acceptable, as long as I can pickle the class in the end.

1 Answers

You could declare a class in the global domain, then, declare it global in the factory function, and overwrite it.
It looks like a bit of a hack, and there might be a better way (maybe by injecting the class directly into the class dict), but nonetheless, here it is:

import pickle

class A:
    pass

class _B:
    pass
B = _B

def extend_class(base_class):
    global B
    class B(base_class):
        def hello(self):
            print('Yo!')

    return B


if __name__ == '__main__':

    extended_class = extend_class(A)

    b = extended_class()
    b.hello()
    with open('tst.pickle', "wb") as f:
        pickle.dump(b, f)
Related