2012-04-07 13 views
1

Ich versuche, ein "Einstieg mit Essiggurken" Skript funktioniert. Ich habe es geschafft, eine Beizdatei aus einer Datei zu speichern und sie zu laden. Aber wenn ich eine Beizdatei in einer Datei (die main.py in diesem Fall) speichern und von einer anderen laden, erhalte ich einen Fehler. Vermutlich habe ich etwas Kleines verpasst, kann aber nicht herausfinden was.eine Pickle-Datei laden

main.py

import pickle 

class Node: 
    """This class represents a node""" 

    def __init__(self, value = None): 
    self.val = value 

    def toString(self): 
    return self.val 


class Link: 
    """This class represents a link between 2 nodes""" 

    def __init__(self, sourceNode, targetNode, LinkWigth): 
    self.source = sourceNode 
    self.target = targetNode 
    self.wight = LinkWigth 

    def setWeight(self, newWeight): 
    self.wight = newWeight 

    def toString(self): 
    return self.wight 

class Graph: 
    """This class represents a graph""" 

    def __init__(self): 
    self.nodes = [] 
    self.links = [] 

    def addNode(self, node): 
    self.nodes.append(node) 

    def addLink(self, link): 
    self.links.append(link) 

    def getInDegree(self, node): 
    counter = 0 
    for link in self.links: 
     if link.target == node: 
     counter +=1 
     else: 
     print "target is: %s" % link.target.toString() 
     print "source is: %s" % link.source.toString() 
    return counter 

    def toString(self): 
    for link in self.links: 
     print link.toString() 
    for node in self.nodes: 
     print node.toString() 


if __name__ == "__main__": 
    n1 = Node(4) 
    l1 = Link(n1, n1, 1) 
    g = Graph() 
    g.addNode(n1) 
    g.addLink(l1) 
    pickle.dump(g, open('haha', 'wb')) 

pickleLoader.py

import pickle 
import main 


n = main.Node(44) 
print n.toString() 
g = pickle.load(open('haha', 'rb')) 
print "ha" 

Der Fehler

C:\Users\R\Desktop\pickle test>main.py 

C:\Users\R\Desktop\pickle test>pickleLoader.py 
44 
Traceback (most recent call last): 
    File "C:\Users\R\Desktop\pickle test\pickleLoader.py", line 7, in <module> 

    g = pickle.load(open('haha', 'rb')) 
    File "C:\Program Files\Python27\lib\pickle.py", line 1378, in load 
    return Unpickler(file).load() 
    File "C:\Program Files\Python27\lib\pickle.py", line 858, in load 
    dispatch[key](self) 
    File "C:\Program Files\Python27\lib\pickle.py", line 1069, in load_inst 
    klass = self.find_class(module, name) 
    File "C:\Program Files\Python27\lib\pickle.py", line 1126, in find_class 
    klass = getattr(mod, name) 
AttributeError: 'module' object has no attribute 'Graph' 

C:\Users\R\Desktop\pickle test> 

Ich denke, dass das Problem etwas mit dem Namensraum ist, weil main.py importiert wurde, aber Ich habe keine Ahnung, wie es funktioniert.

Antwort

0

Dies scheint zu sein, wie die Klassen in Bezug auf das Modul definiert sind. Eine schnelle Möglichkeit, dies zu Arbeit zu ermöglichen, ist die Komponenten des main Modul direkt in pickleLoader zu importieren:

from main import Graph, Node, Link 

Eine bessere Lösung könnte darin bestehen, die gemeinsame Komponenten zu bewegen (Grafik, Knoten, Verbindung) in ihr eigenes Modul, und dann dieses Modul in beide main und pickleLoader importieren.

+0

Dank seiner Arbeit. Aber warum ist es besser, diese 3 Komponenten auf ein anderes Modul zu verschieben? Was wird sich ändern? –

+1

Wenn Sie sie in ein separates Modul einfügen (und dieses Modul importieren), können Sie Namespace-Kollisionen vermeiden. Der aktuelle Ansatz erfordert, dass die Typen in den aktuellen Namespace gebracht werden. Platzieren Sie sie in einem separaten Modul und importieren Sie sie so, dass sie in ihrem eigenen Namensraum bleiben. – DRH