AttributeError: объект 'module' не имеет атрибута (при использовании cPickle)
Я пытаюсь загрузить функцию в удаленной среде с помощью cPickle. Но я получил
ошибка "объект 'module' не имеет атрибута...". Где я действительно застрял, пространство имен
уже содержат эти атрибуты, даже если он не загружается
Пожалуйста, помогите
import inspect
import cPickle as pickle
from run import run
def get_source(func):
sourcelines = inspect.getsourcelines(func)[0]
sourcelines[0] = sourcelines[0].lstrip()
return "".join(sourcelines)
def fun(f):
return f()
def fun1():
return 10
funcs = (fun, fun1)
sources = [get_source(func) for func in funcs]
funcs_serialized = pickle.dumps((fun.func_name,sources),0)
args_serialized = pickle.dumps(fun1,0)
#Creating the Environment where fun & fun1 doesnot exist
del globals()['fun']
del globals()['fun1']
r = run()
r.work(funcs_serialized,args_serialized)
Вот run.py
import cPickle as pickle
class run():
def __init__(self):
pass
def work(self,funcs_serialized,args_serialized):
func, fsources = pickle.loads(funcs_serialized)
fobjs = [compile(fsource, '<string>', 'exec') for fsource in fsources]
#After eval fun and fun1 should be there in globals/locals
for fobj in fobjs:
try:
eval(fobj)
globals().update(locals())
except:
pass
print "Fun1 in Globals: ",globals()['fun1']
print "Fun1 in locals: ",locals()['fun1']
arg = pickle.loads(args_serialized)
Ошибка
Fun1 in Globals: <function fun1 at 0xb7dae6f4>
Fun1 in locals: <function fun1 at 0xb7dae6f4>
Traceback (most recent call last):
File "fun.py", line 32, in <module>
r.work(funcs_serialized,args_serialized)
File "/home/guest/kathi/python/workspace/run.py", line 23, in work
arg = pickle.loads(args_serialized)
AttributeError: 'module' object has no attribute 'fun1'
Ответы
Ответ 1
Я нашел эту ссылку полезной:
http://stefaanlippens.net/python-pickling-and-dealing-with-attributeerror-module-object-has-no-attribute-thing.html
Это дает два решения. Лучшим решением является добавление в голову модуля загрузки (или __main__
):
from myclassmodule import MyClass
Но я думаю, что лучшее решение должно существовать.
Ответ 2
От http://docs.python.org/library/pickle.html#what-can-be-pickled-and-unpickled:
Обратите внимание, что функции (встроенные и определяемые пользователем), маринованные "полностью квалифицированной" ссылкой на имя, а не стоимость. Это означает, что только имя функции маринованное, наряду с имя модуля - функция не определено. Ни функции кода или любой его функции атрибуты маринованные. Таким образом определяющий модуль должен быть импортирован в нераскрывающаяся среда и модуль должен содержать именованный объект, в противном случае будет создано исключение.
Вы удалили ссылку на fun1 в модуле, который определяет fun1, таким образом, ошибку.
Ответ 3
попытайтесь добавить
from your_first_module import fun,fun1
в run.py
Ответ 4
Имя модуля функции сохраняется в рассоле, когда вы выполняете loads
, он ищет fun1
в __main__
или независимо от того, изначально он был