2010-07-29 95 views
12

我想使用cPickle在遠程環境中加載函數。但我得到了 錯誤「模塊」對象沒有屬性...「。凡我很堅持是命名空間具有 已經包含了屬性,即使它無法加載 請幫助AttributeError:'模塊'對象沒有任何屬性(當使用cPickle時)

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' 

回答

0

功能的模塊名稱被保存到泡菜中,當你在做loads它正在尋找fun1__main__或徘徊無論它最初

+0

因此,如何FUN1是融入模塊,說跑 – 2010-07-29 15:26:32

6

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.

您定義FUN1模塊中刪除提及FUN1,從而錯誤。

+0

我故意刪除了參考,但eval()函數時再次是 命名空間中的 – 2010-07-29 15:21:03

+1

重建不看太深入到它,我會想象中的eval定義函數在運行模塊的全局範圍內,而不是最初定義它的模塊(可能是'__main__'?)。更好地執行測試將會在另一個模塊(「my_funcs.py」)中定義維護對函數對象的引用的函數。請記住,函數對象並不是真正的pickle - 只是完全限定的名稱。它定義的模塊必須是可導入的,並且它必須具有作爲屬性的函數名稱。 – 2010-07-29 15:28:24

+1

你是否熟悉並行python?他們做的方式完全一樣,他們醃製func及其參數併發送到運行函數。 但是當它們執行run()時,它執行完美。我想知道他們如何實現它,接觸並行python更好嗎? – 2010-07-29 15:52:15

1

嘗試添加

from your_first_module import fun,fun1 

到run.py

相關問題