2016-10-27 43 views
7

我在加載pickled文件的模塊與我在pickled文件的模塊不同時遇到了一些麻煩。我知道以下線程:Unable to load files using pickle and multipile modules。我試圖導入全班分成我在哪裏取儲存我的文件模塊的提出的解決方案,但它不斷給我同樣的錯誤: AttributeError: Can't get attribute 'Document' on <module '__main__' from ''> 在不同的文件中加載pickled對象 - 屬性錯誤

的什麼,我試圖做的基本結構:

其中文檔對象被定義並且保存util的方法

import pickle 

def save_document(doc): 

    from class_def import Document 

    write_file = open(file_path, 'wb') 
    pickle.dump(doc, write_file) 

def load_document(file_path): 
    from class_def import Document 

    doc_file = open(file_path, 'rb') 
    return pickle.load(doc_file) 

文件被調用時,class_def.py:該泡菜和unpickles目的,utils.py

的Util文件

​​

文件,其中負載UTIL方法被調用,process.py:

import utils 

if __name__ == '__main__': 
    utils.load_document(file_path) 

運行process.py給出提到AttributeError的。如果我將class_def.py文件導入process.py並運行其原始線程中提到的main方法,但是我希望能夠分別運行這兩個模塊,因爲class_def文件是一個預處理步驟,需要相當一段時間。我怎麼能解決這個問題?

+0

不回答你的問題,但你應該在你打開它們後關閉文件處理程序,或者乾脆用['with'](http://effbot.org/zone/python-with-statement .htm)。 – Itay

+0

當一個文件以'__main__'的形式運行時,其中定義的任何東西都被作爲'__main__'模塊的成員來醃製,所以如果你正在加載到另一個文件中,它就會失敗。來自<__main__>模塊的東西最快的修復是從<這個模塊名稱> import *',但我不建議在生產代碼中使用它。 –

+0

[python pickle上的命名空間](http:// stackoverflow。 com/q/7928450/5827215),但我認爲可能有更好的線程標記爲dup –

回答

9

class_def.py文件,你有這樣的代碼:

if __name__ == '__main__': 
    doc = Document() 
    utils.save_document(doc) 

這意味着doc將是一個__main__.Document對象,所以當它醃它被期待能夠從主模塊得到Document類,解決這個問題,你需要使用的Document定義從一個叫class_def意思模塊,你會在這裏添加導入:

if __name__ == '__main__': 
    from class_def import Document 
    #^so that it is using the Document class defined under the class_def module 
    doc = Document() 
    utils.save_document(doc) 

這樣,它需要運行class_def.py文件兩次,一次爲__main__,一次爲class_def,但確實意味着數據將被醃製爲class_def.Document對象,因此加載它將從正確的位置檢索該類。否則,如果您有從另一個構建一個文檔對象,你可以做這樣的事情在utils.py的一種方式:

def save_document(doc): 
    if doc.__class__.__module__ == "__main__": 
     from class_def import Document #get the class from the reference-able module 
     doc = Document(doc) #convert it to the class we are able to use 


    write_file = open(file_path, 'wb') 
    pickle.dump(doc, write_file) 

雖然平時我更喜歡第一種方式。

1

我有一個類似的問題,只是意識到我們的實現之間的差異。

你的文件結構:

  • util.py
    • 定義鹹菜功能
  • class_def。PY
    • 進口UTIL
    • 定義類
    • 使實例
    • 調用保存泡菜
  • process.py
    • 進口UTIL
    • 負載泡菜

我的錯誤(使用文件名)第一次:

  • util_and_class.py
    • 定義類
    • 定義泡菜funcs中
    • 使實例
    • 通話保存泡菜
  • process.py
    • 進口util_and_class
    • 呼叫負載泡菜< < ERROR

什麼解決我的泡菜進口問題:

  • util_and_class.py
    • 定義類
    • 定義泡菜funcs中
  • pickle_init.py
    • 進口util_and_class
    • 使實例
    • 調用保存泡菜
  • process.py
    • 呼叫負載泡菜

這不得不說,因爲它是烤成鹹菜文件我並不需要導入util_and_class文件歡迎副作用。調用實例並將pickle保存在一個單獨的文件中,解決了問題「在與我對文件進行pickle的模塊不同的模塊中加載pickle文件。「