Подтвердить что ты не робот

AttributeError при распаковке объекта

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

Здесь, где я мариную:

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'

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

4b9b3361

Ответ 1

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

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

В этом примере вы можете переопределить class Foo в рассыпном script, и он должен быть полностью разборчив. Но намерение состоит в том, чтобы иметь общую библиотеку, которая разделяется между двумя сценариями, которые будут доступны по тому же пути. Пример: define 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)
...

Ответ 2

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

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 живет в одном пространстве имен в каждом фрагменте кода.