Harikrishnan R Harikrishnan R -4 years ago 307
Python Question

AttributeError: 'module' object has no attribute (when using cPickle)

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'

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download