Python-Beizen nach dem Ändern des Modul-Verzeichnisses

Ich habe vor kurzem mein Verzeichnis Verzeichnis Layout geändert: vorher hatte ich alle meine Module im "Haupt" Ordner. Jetzt habe ich sie in ein nach dem Programm benanntes Verzeichnis verschoben und dort ein __init__.py platziert.

Jetzt habe ich eine einzelne .py-Datei in meinem Hauptverzeichnis, das verwendet wird, um mein Programm zu starten, das ist viel schöner.

  • Einstufung einer Klassendefinition
  • AttributeError beim Entschlüsseln eines Objekts
  • Wie man ein Wörterbuch in Gurke speichert
  • ImportError: Kein Modul namens copy_reg pickle
  • Kann ich Variablen als vorübergehend markieren, damit sie nicht gebeizt werden?
  • Wie man die Attribute in Python
  • Wie auch immer, der Versuch, in gebeizten Dateien aus früheren Versionen meines Programms zu laden, scheitert. Ich bekomme, "ImportError: Kein Modul namens Tools" – was ich vermute, weil mein Modul zuvor im Hauptordner war, und jetzt ist es in Whyteboard.tools, nicht einfach einfacher Tools. Allerdings lebt der Code, der im Tools-Modul importiert wird, im selben Verzeichnis wie es, also bezweifle ich, dass es notwendig ist, ein Paket anzugeben.

    Also, mein Programmverzeichnis sieht so aus:

    whyteboard-0.39.4

    -->whyteboard.py

    -->README.txt

    -->CHANGELOG.txt

    ---->whyteboard/

    ---->whyteboard/__init__.py

    ---->whyteboard/gui.py

    ---->whyteboard/tools.py

    Whyteboard.py startet einen Codeblock von Whyteboard / gui.py, der die GUI auslöst. Dieses Beizproblem war definitiv nicht passiert, bevor das Verzeichnis neu organisiert wurde.

  • Unerwartetes Verhalten von Extend mit einer Liste in Python
  • Erstellen einer Liste Unterklasse hashable
  • Was wäre ein "gefrorenes Dict"?
  • Sind benutzerdefinierte Klassen veränderlich
  • Warum wird list.append auf false ausgewertet?
  • Python: Warum kann ich veränderliches Objekt in einen Dict oder Set setzen?
  • 4 Solutions collect form web for “Python-Beizen nach dem Ändern des Modul-Verzeichnisses”

    Wie die Essiggursten sagen, um eine Klasseninstanz zu speichern und wiederherzustellen (eigentlich auch eine Funktion), müssen Sie bestimmte Einschränkungen beachten:

    Pickle kann die Klasseninstanzen transparent speichern und wiederherstellen, aber die Klassendefinition muss importierbar sein und in demselben Modul leben, wie wenn das Objekt gespeichert wurde

    whyteboard.tools ist nicht das "das gleiche Modul wie" tools (auch wenn es durch import tools von anderen Modulen im selben Paket importiert werden kann, endet es in sys.modules als sys.modules['whyteboard.tools'] : Das ist absolut entscheidend, sonst würde das gleiche Modul, das von einem im selben Paket vs eins in einem anderen Paket importiert wird, mit mehreren und möglicherweise widersprüchlichen Einträgen enden!).

    Wenn Ihre Pickle-Dateien in einem guten / erweiterten Format sind (im Gegensatz zu den alten ascii-Format, das ist der Standard nur aus Kompatibilitätsgründen), migrieren sie, sobald Sie solche Änderungen durchführen können in der Tat nicht ganz so trivial wie "Bearbeitung der Datei" ( Was ist binary & c …!), Trotz was eine andere Antwort vorschlägt. Ich schlage vor, dass du stattdessen ein kleines " sys.modules script" sys.modules : lass es patch sys.modules wie sys.modules …:

     import sys from whyteboard import tools sys.modules['tools'] = tools 

    Und dann cPickle.load jede Datei, del sys.modules['tools'] und cPickle.dump jedes geladene Objekt zurück in Datei: Der temporäre Zusatzeintrag in sys.modules sollte die Gurken erfolgreich laden lassen, dann muss man sie wieder sys.modules Mit dem richtigen Modul-Namen für die Instanzen 'Klassen (Entfernen, dass zusätzliche Eintrag sollte sicherstellen, dass).

    pickle serialisiert Klassen durch Verweis, also wenn Sie sich ändern, waren die Klasse lebt, wird es nicht entfesseln, weil die Klasse nicht gefunden wird. Wenn du dill anstelle von pickle , kannst du Klassen per Referenz oder direkt serialisieren (indem du direkt die Klasse anstelle des Importpfads serialisierst). Sie simulieren diese ziemlich leicht, indem Sie einfach die Klassendefinition nach einem dump und vor einer load ändern.

     Python 2.7.8 (default, Jul 13 2014, 02:29:54) [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import dill >>> >>> class Foo(object): ... def bar(self): ... return 5 ... >>> f = Foo() >>> >>> _f = dill.dumps(f) >>> >>> class Foo(object): ... def bar(self, x): ... return x ... >>> g = Foo() >>> f_ = dill.loads(_f) >>> f_.bar() 5 >>> g.bar(4) 4 

    Dies ist das normale Verhalten von Gurken, unpickled Objekte müssen ihre definierende Modul importierbar sein .

    Sie sollten in der Lage sein, den whyteboard.tools (dh von den tools zu whyteboard.tools ) zu whyteboard.tools indem Sie die gebeizten Dateien bearbeiten, da sie normalerweise einfache Textdateien sind.

    Es geschah mit mir, löste es, indem ich den neuen Standort des Moduls zu sys.path hinzufügte, bevor ich Pickle lade:

     import sys sys.path.append('path/to/whiteboard') pickle.load(f) 
    Python ist die beste Programmiersprache der Welt.