Как разблокировать объект, класс которого существует в другом пространстве имен (python)?

Если у меня есть скрипт, который определяет класс:

script = """ class myClass: def __init__(self): self.name = 'apple' self.color = 'green' """ 

а затем выполните этот скрипт в своем собственном пространстве имен dict:

 NS = {} exec script in NS 

а затем создать экземпляр класса и рассортировать его:

 a = NS['myClass']() import pickle save = pickle.dumps(a) 

Теперь, если я попытаюсь раскрыть ее:

 load = pickle.loads(save) 

Я получаю ошибку

 AttributeError: 'module' object has no attribute 'myClass' 

Я понимаю, что это не работает, потому что python не знает, где найти myClass, чтобы перестроить объект. Но myClass существует в NS dict. Есть ли способ сказать pickle, где найти класс для объекта, который он загружает?

2 Solutions collect form web for “Как разблокировать объект, класс которого существует в другом пространстве имен (python)?”

Я обнаружил решение этого. Кажется, что проблема заключается в выполнении кода в dict запрещает python определять, где определяется класс. Решение состоит в том, чтобы создать пустой модуль, выполнить код в модуле, а затем добавить модуль в sys.modules, чтобы python знал об этом.

 script = """ class myClass: def __init__(self): self.name = 'apple' self.color = 'green' """ import imp, sys moduleName = 'custom' module = imp.new_module(moduleName) exec script in module.__dict__ sys.modules[moduleName] = module 

Теперь можно рассортировать и распечатывать экземпляр класса:

 import pickle a = module.myClass() s = pickle.dumps(a) b = pickle.loads(s) 

Вы можете пойти на один шаг дальше и восстановить объект в том виде, который вам нужен.

 import pickle import copy_reg class myClass(object): def __init__(self): self.apple = 'banana' class otherclass(object): def __init__(self): self.apple = 'existential woe' def pickle_an_object(o): print "pickling %s" % str(o) return otherclass, (o.apple,) copy_reg.pickle(myClass, pickle_an_object) foo = myClass() s = pickle.dumps(foo) del myClass del otherclass class otherclass(object): def __init__(self, appletype): self.apple = 'not %s' % appletype o2 = pickle.loads(s) print o2.apple 

Основная идея заключается в том, что вы кладете свой класс в «троянскую лошадь», где его реконструкция создает экземпляр другого класса из того, что он изначально был.

Не имеет значения, что otherclass на травильной стороне. Все, что имеет значение, заключается в том, что он существует на том же пути модуля, что и класс «destination» – pickle просто помещает строковое представление имени модуля в сериализованный поток.

Итак, чтобы разложить то, что происходит в приведенном выше коде в деталях:

  • Мы регистрируем пользовательский pickler для myClass . Это можно сделать с помощью функции copy_reg или __reduce_ex__ .
  • Наш заказчик говорит, что «расчешите это как экземпляр otherclass » (который является манекеном. Вам не нужно «настоящее» содержимое otherclass на травильной стороне, потому что все, что входит в рассол, – это имя модуля / класса).
  • Мы сортируем объект и «отправляем его по проводам», где существует реальная версия otherclass .
  • С другой стороны, otherclass с данными из кортежа, возвращаемого пользовательской функцией травления.

Python может быть довольно мощным!

  • Как я распечатываю серию объектов из файла в Python?
  • Как восстановить маринованный класс и его экземпляры
  • Как распиливать и распаковывать экземпляры класса, который наследуется от defaultdict?
  • Могу ли я пометить переменные как переходные, чтобы они не были маринованными?
  • `_pickle.UnpicklingError: аргумент кода STRING должен быть указан`
  • Почему нельзя использовать эллипсис и NotImplemented?
  • Ошибка Pilton Pickling Slots
  • AttributeError при распаковке объекта
  •  
    Interesting Posts for Van-Lav

    Можно ли запустить серверный javascript из экземпляра * Python * Google App Engine?

    Может ли random.randint (1,10) когда-либо возвращаться 11?

    Как конструкторы производных классов работают в python?

    Как реализовать безопасную проверку подлинности с помощью xml-rpc в python?

    Только данные HTTP-заголовка Scrapy

    Прогнозирование ARMA вне выборки с помощью statsmodels

    PyQt 4 – глобальное имя «СИГНАЛ» не определено

    Получение идентификатора cx для пользовательского поиска, API Google – Python

    Объединить файлы PDF

    Как открыть текстовый файл юникода внутри zip?

    Почему этот сценарий оболочки называется скриптом python?

    Почему json.dumps (list (np.arange (5))) сбой, тогда как json.dumps (np.arange (5) .tolist ()) работает

    Разница между __getattr__ vs __getattribute__

    Можно ли проверить, уже ли задана переменная контекста в представлении в определении пользовательского контекстного процессора?

    Фильтр данных Pandas с другой серией

    Python - лучший язык программирования в мире.