I am trying to pickle a dynamically generated class as a factory for an alternative class. Something like the following:
import sys, pickle
class BC(object):
pass
C = type("NewClassName", (BC,), {})
pickle.dump(C, sys.stdout)
This leads to the following error:
pickle.PicklingError: Can't pickle <class '__main__.NewClassName'>: it's not found as __main__.NewClassName
For pickling an object of a dynamically generated class, you can define an __reduce__
method, but is there a way to achieve this only for a class definition.
I don't want to use BC directly, because I only need it as a factory for new classes.
A simple workaround to the error is to use the class name as variable name so that
pickle
can find it:However, this probably doesn't really do what you want. When loading the pickled class:
You again get the error:
unless you've already defined the class.
As the documentation states:
So you can't use it to generate new classes, just to make sure your objects refer to the correct classes.
There are workarounds like pickling
type
parameters as shown in the other answer, but even then you will not be able to pickle objects of those dynamic classes without exposing the class in the global namespace of both the pickling and the unpickling process (i.e.__main__.ClassName
must refer to the class).Therefore, I would rethink the whole dynamic class approach.