I am trying to load the function in a remote environment using cPickle. But I got the error "the 'module' object has no attribute ..." . Where I really stuck is the namespace has already contain that attributes , even though it fails to load Please Help
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)
Here is 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)
The error is
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'
I found this link helpful: http://stefaanlippens.net/python-pickling-and-dealing-with-attributeerror-module-object-has-no-attribute-thing.html
It gives two solutions. The better solution is to add to the head of the loading module (or __main__
):
from myclassmodule import MyClass
But I think a better solution should exist.
From http://docs.python.org/library/pickle.html#what-can-be-pickled-and-unpickled:
Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.
You deleted the reference to fun1 in the module that defines fun1, thus the error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With