Я пытаюсь выделить экземпляр класса в одном модуле и разобрать его в другом.

Вот где я маринуют:

import cPickle

def pickleObject():
    object = Foo()
    savefile = open('path/to/file', 'w')
    cPickle.dump(object, savefile, cPickle.HIGHEST_PROTOCOL)


class Foo(object):
    (...)

И вот где я пытаюсь разобрать:

savefile = open('path/to/file', 'r')
object = cPickle.load(savefile)

Во второй строке я получаю AttributeError: 'module' object has no attribute 'Foo'

Кто-нибудь видит, что я делаю неправильно?

18
Max 1 Сен 2010 в 05:10

2 ответа

Лучший ответ

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

Я думаю, ваша проблема в том, что вы определяете Foo в модуле, который вы выполняете, как основной (__name__ == "__main__"). Pickle сериализует путь (не объект / определение класса !!!) к Foo как находящийся в основном модуле. Foo не является атрибутом основного скрипта unpickle.

В этом примере вы можете переопределить class Foo в скрипте unpickling, и он должен нормально распаковаться. Но на самом деле цель состоит в том, чтобы иметь общую библиотеку, которая используется двумя сценариями и будет доступна по одному и тому же пути. Пример: определить Foo в foo.py

Простой пример:

$ PROJECT_DIR / foo.py

class Foo(object):
    pass

$ PROJECT_DIR / picklefoo.py

import cPickle
from foo import Foo

def pickleObject():
    obj = Foo()
    savefile = open('pickle.txt', 'w')
    cPickle.dump(obj, savefile, cPickle.HIGHEST_PROTOCOL)


pickleObject()

$ PROJECT_DIR / unpicklefoo.py

import cPickle

savefile = open('pickle.txt', 'r')
obj = cPickle.load(savefile)
...
25
Jeremy Brown 1 Сен 2010 в 01:38

Джереми Браун дал правильный ответ, вот более конкретная версия того же пункта:

import cPickle
import myFooDefiningModule
def pickleObject():
    object = myFooDefiningModule.Foo()
    savefile = open('path/to/file', 'w')
    cPickle.dump(object, savefile)

А также:

import cPickle
import myFooDefiningModule
savefile = open('path/to/file', 'r')
object = cPickle.load(savefile)

Таким образом, что Foo находится в одном и том же пространстве имен в каждой части кода.

3
msw 1 Сен 2010 в 01:37