Eingelegtes Objekt kann nicht geladen werden

72

Das Problem, das ich habe, ist, wenn ich versuche, das eingelegte Objekt zu laden . Ich habe versucht, beide zu verwenden pickle.loadsund pickle.loadhier sind die Ergebnisse:

pickle.loads::

TypeError: 'str' unterstützt die Pufferschnittstelle nicht

pickle.load::

TypeError: Die Datei muss die Attribute 'read' und 'readline' haben

Kann mir bitte jemand sagen, was ich in diesem Prozess falsch mache?

elif str(parser) == "SwissWithdrawn_Parser":
    # swissprot name changes
    print("Gathering SwissProt update info...")
    cache_hits = 0
    cache_misses = 0
    files = set()

    for f in os.listdir("out/cache/"):
        if os.path.isfile("out/cache/" + f):
            files.add(f)

    for name in sp_lost_names:

        cached = False
        url = (
            "http://www.uniprot.org/uniprot/?query=mnemonic%3a"
            + name
            + "+active%3ayes&format=tab&columns=entry%20name"
        )
        hashed_url = str(hash(url))

        ################### For Testing Only - use cache ##################
        if hashed_url in files:
            cached = True
            cache_hits += 1
            content = pickle.loads("out/cache/" + hashed_url)  # <-- problematic line
        else:
            cache_misses += 1
            content = urllib.request.urlopen(url)

        # get the contents returned from the HTTPResponse object
        content_list = [x.decode().strip() for x in content.readlines()]
        if not cached:
            with open("out/cache/" + hashed_url, "wb") as fp:
                pickle.dump(content_list, fp)
        ####################################################################

        # no replacement
        if len(content_list) is 0:
            change_log["swiss-names"] = {name: "withdrawn"}
        # get the new name
        else:
            new_name = content_list[1]
            change_log["swiss-names"] = {name: new_name}
Houdini
quelle

Antworten:

108

Sie müssen entweder zuerst die Datei lesen (als Binärdatei bytes) und verwenden pickle.loads()oder ein geöffnetes Dateiobjekt an den pickle.load()Befehl übergeben. Letzteres ist vorzuziehen:

with open('out/cache/' +hashed_url, 'rb') as pickle_file:
    content = pickle.load(pickle_file)

Keine der beiden Methoden unterstützt das Laden einer Gurke aus einem Dateinamen.

Martijn Pieters
quelle
0

Wenn Sie python2 auf 3 portieren und auf diesen Fehler stoßen, behandeln python2 und 3 unterschiedliche Bytes, was dazu führt, dass Sie Ihr Dateihandle mit der Option 'b' öffnen müssen. Zum Beispiel in Python2 open(file, 'r') as f: my_list = pickle.load(f)funktioniert, aber nicht in Python3. Stattdessen müssen Sie mit öffnenopen(file, 'rb') as f: my_list = pickle.load(f)

Kyle Meador
quelle