2016-10-27 2 views
7

Ich habe Probleme beim Laden einer gebeizten Datei in einem Modul, das sich von dem Modul unterscheidet, in dem ich die Datei gebeizt habe. Ich kenne den folgenden Thread: Unable to load files using pickle and multipile modules. Ich habe die vorgeschlagene Lösung der Import der Klasse in das Modul versucht, wo ich meine Datei bin Unpickling, aber es hält mich den gleichen Fehler geben: AttributeError: Can't get attribute 'Document' on <module '__main__' from ''> Beladenes Objekt in anderer Datei laden - Attributfehler

Die Grundstruktur von dem, was ich zu tun versucht:

util-Datei, die Gurken und unpickles Objekte, utils.py:

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) 

Datei in dem Dokument-Objekt definiert ist und die util Methode speichern genannt wird, class_def.py:

import utils 

class Document(object): 
    data = "" 

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

Datei, wo die Last util-Methode aufgerufen wird, process.py:

import utils 

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

Lauf process.py gibt dem erwähnten Attribute. Wenn ich die Datei class_def.py in process.py importiere und ihre Hauptmethode wie im ursprünglichen Thread erwähnt ausführe, funktioniert sie, aber ich möchte diese beiden Module separat ausführen können, da die Datei class_def ein Vorverarbeitungsschritt ist, der ziemlich dauert irgendwann. Wie könnte ich das lösen?

+0

Beantwortet Ihre Frage nicht, aber Sie sollten die Dateihandler schließen, nachdem Sie sie geöffnet haben, oder einfach [' mit'] (http://effbot.org/zone/python-with-statement .htm). – Itay

+0

Wenn eine Datei als '__main__' ausgeführt wird, werden alle darin definierten Elemente als Mitglieder des' __main__' - Moduls markiert. Wenn Sie also in eine andere Datei laden, schlägt das fehl Dinge aus anderen Modulen als '' __main__' die schnellste Lösung ist 'von import *' aber ich empfehle es nicht im Produktionscode –

+0

mögliches Duplikat von [namespace on python pickle] (http: // stackoverflow. com/q/7928450/5827215), aber ich denke, es könnte einen besseren Thread als dup markieren –

Antwort

9

in Ihrer class_def.py Datei haben Sie diesen Code:

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

Das bedeutet, dass doc ein Objekt __main__.Document sein wird, so dass, wenn es gebeizt wird erwartet eine Document Klasse aus dem Hauptmodul erhalten zu können, , um dieses Problem beheben Sie die Definition von Document aus einem Modul namens verwenden müssen class_def bedeutet, dass Sie einen Import hier hinzufügen würden:

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) 

auf diese Weise wird es ausführen müssen die Datei class_def.py zweimal, einmal als __main__ und einmal als class_def, aber es bedeutet, dass die Daten als class_def.Document Objekt gebeizt werden, so dass das Laden der Klasse von der richtigen Stelle abgerufen wird. Andernfalls, wenn Sie eine Möglichkeit des Aufbaus eines Dokuments Objekt von einem anderen haben Sie so etwas wie dies in utils.py tun können:

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) 

Obwohl in der Regel würde ich die erste Möglichkeit bevorzugen.

1

Ich hatte ein ähnliches Problem und erkannte nur die Unterschiede zwischen unseren Implementierungen.

Ihre Dateistruktur:

  • util.py
    • definieren Beize Funktionen
  • class_def.py
    • Import util
    • definieren Klasse
    • machen Instanz
    • Aufruf speichern Beize
  • process.py
    • Import util
    • Last Beize

Mein Fehler (die Dateinamen verwendet wird) wurde zuerst:

  • util_and_class.py
    • definieren Klasse
    • definieren Gurke funcs
    • Instanz
    • Anruf Sicher Gurke
  • process.py
    • Import util_and_class
    • Rufbelastung Beize < < ERROR

Was meine Gurke Import Problem gelöst:

  • util_and_class.py
    • definieren Klasse
    • Beize funcs
  • pickle_init.py
    • Import util_and_class
    • Instanz
    • Aufruf speichern Gurke machen definieren
  • process.py
    • Rufbelastung Beize

Dies hatte den begrüßt Nebeneffekt, dass ich brauche nicht die util_and_class-Datei zu importieren, da es in die Beize Datei gebacken wird. Der Aufruf der Instanz und das Speichern der Beize in einer separaten Datei löste das __name__ Problem von "Laden einer gebeizten Datei in einem Modul, das sich von dem Modul unterscheidet, in dem ich die Datei gebeizt habe."

Verwandte Themen