Python: сохранение динамически создаваемых типов объектов - PullRequest
6 голосов
/ 18 марта 2011

Я создаю некоторые типы объектов динамически, используя функцию типа.Пример

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

Дикт зависит от ввода пользователя.Теперь я хочу, чтобы у меня была возможность сохранить этот возвращаемый тип класса и использовать один и тот же тип для разных сеансовОдин из возможных способов - сохранить текст в виде текста (или в базе данных) и снова создать этот тип объекта из этого слова.Но есть ли другой способ, которым я могу сохранить «тип» напрямую?

Ответы [ 7 ]

3 голосов
/ 04 апреля 2011

Вы не можете выбрать классы, даже если вы решите проблему "... не найден как ...", она все равно не будет работать (как при сохранении имени класса без содержимого, затем не сможет unpickle, потому что класс не существует после перезапуска вашей программы)

В дальнейшем вам придется вручную сериализовать dict и реконструировать класс из него, что в зависимости от того, что он содержит, также будет забавным: функциональные объекты не могут быть сериализованы ничем, вы должны извлечь их объекты кода, сериализовать их с помощью marshal , затем воссоздайте их при загрузке.

2 голосов
/ 07 апреля 2011

Как насчет создания класса Factory с методами для создания, выбора и выделения динамически создаваемых объектов типа?Следующее - грубое начало.Для использования просто замените вызовы pickle.dump (type, fh) на TypeFactory.pickle (type, fh) и замените вызовы pickle.load (fh) на 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)
1 голос
/ 18 марта 2011

В python классы также являются объектами.Таким образом, вы должны иметь возможность выбирать объекты класса и сохранять их в файл.Затем вы можете распаковать их позже.

0 голосов
/ 10 апреля 2011

Нет автоматического решения для вашего вопроса.Все механизмы «по умолчанию», такие как pickle, просто сохраняют данные экземпляра (включая метаданные, такие как тип).Что вы хотите сделать, это сохранить класс тоже.Возможно, вам удастся создать что-то, используя магию байт-кода, но, вероятно, проще реализовать собственный код сериализации.

0 голосов
/ 05 апреля 2011

Вы можете «внедрить» новый класс в глобальное пространство имен перед выбором, чтобы избежать ошибки:

import pickle

class TestClass(object):
    def __init__(self):
        self.a = 1     # Initial instance attributes
        self.b = 2
        self.c = 3

my_classname = "NewTestClass"
obj = type(my_classname, (TestClass,), {})()
obj.d = 4                # Extra attributes
print obj.a, obj.b, obj.c, obj.d
print obj.__class__

globals()[my_classname] = obj.__class__     # Inject the new class in the global namespace

obj2 = pickle.dumps(obj)
obj = None           # Free original obj instance
obj = pickle.loads(obj2)
print obj.a, obj.b, obj.c, obj.d   # 1,2,3,4
0 голосов
/ 04 апреля 2011

Сохранение dict в JSON кажется наиболее простым, однако похоже, что pickle или shelve можно использовать для создания некоторой динамической сериализации классов.

Быстрый поиск по SO показывает этот полезный пост: получение пути к классу или пространства имен класса в python, даже если он вложенный

0 голосов
/ 04 апреля 2011

Может быть, вы могли бы попробовать модуль json (примечание: я сам не использовал его, поэтому не знаю, решит ли он вашу проблему, это всего лишь предложение):

"Модуль json предоставляетAPI, похожий на pickle, для преобразования объектов Python в памяти в сериализованное представление, известное как JavaScript Object Notation (JSON). В отличие от pickle, преимущество JSON заключается в наличии реализаций на многих языках (особенно JavaScript), что делает его пригодным для межприложений.JSON, вероятно, наиболее широко используется для связи между веб-сервером и клиентом в приложении AJAX, но не ограничивается этой проблемной областью. (...) "

Модуль JSON в PythonМодуль сайта Недели

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...