Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Save dynamically created object types

I'm creating some object types dynamically using type function. Ex

return type('DynamicType', (object,), dict)

The dict depends on user input. Now I want that I should be able to save this returned class type and use the same one over different sessions. One possible method is to save the dict as text(or into database) and creating this object type again from that dict. But is there any other way in which I can save the "type" directly?

like image 963
Neo Avatar asked Mar 18 '11 08:03

Neo


2 Answers

How about creating a Factory class with methods to create, pickle, and unpickle dynamically created type objects? The following is a rough start. To use, simply replace calls to pickle.dump(type, fh) with TypeFactory.pickle(type, fh), and replace calls to pickle.load(fh) with TypeFactory.unpickle(fh).

import pickle

class TypeFactory(object):
    def __init__(self):
        pass
    @staticmethod
    def create_type(name='DynamicType', dict={}):
        return type(name, (object,), dict)
    @staticmethod
    def pickle(t, fh):
        dict = t.__dict__.copy()
        name = t.__name__
        for key in dict.keys():
            if key.startswith('__') and key.endswith('__'):
                del dict[key]
        pickle.dump((name, dict), fh)
    @classmethod
    def unpickle(cls, fh):
        name, dict = pickle.load(fh)
        return cls.create_type(name, dict)
like image 70
Garrett Avatar answered Sep 18 '22 09:09

Garrett


You can't pickle classes, even if you solve your "... not found as ..." problem it still won't work (as in save the name of the class, without the content, then fail to unpickle because the class doesn't exist after your program restarts)

You will have to manually serialize dict and reconstruct the class from it later on, which depending on what it contains will be fun too: function objects can't be serialized by anything, you have to extract their code objects, serialize them with marshal then recreate them when loading.

like image 37
bdew Avatar answered Sep 18 '22 09:09

bdew