AttributeError ("'str' Objekt hat kein Attribut 'read'")

133

In Python erhalte ich eine Fehlermeldung:

Exception:  (<type 'exceptions.AttributeError'>,
AttributeError("'str' object has no attribute 'read'",), <traceback object at 0x1543ab8>)

Gegebener Python-Code:

def getEntries (self, sub):
    url = 'http://www.reddit.com/'
    if (sub != ''):
        url += 'r/' + sub

    request = urllib2.Request (url + 
        '.json', None, {'User-Agent' : 'Reddit desktop client by /user/RobinJ1995/'})
    response = urllib2.urlopen (request)
    jsonofabitch = response.read ()

    return json.load (jsonofabitch)['data']['children']

Was bedeutet dieser Fehler und was habe ich getan, um ihn zu verursachen?

RobinJ
quelle
186
Ich mag jsonofabitchVariablennamen.
Mo Calamari
6
Haha! Was ist das "jsonofabitch"? : D
Bahadir Tasdemir
13
Scheint, als hätten die Moderatoren von Stackoverflow zur Abwechslung einen Sinn für Humor ...
Pepito Fernandez
6
2019 und das ist immer noch lustig: P
Rishav
1
In der Tat, machte meinen Tag, danke aus der Zukunft :)
Pesche Helfer

Antworten:

186

Das Problem ist, dass json.loadSie ein dateiähnliches Objekt mit einer readdefinierten Funktion übergeben sollten. Also entweder du benutzt json.load(response)oder json.loads(response.read()).

kosii
quelle
3
Ich verstehe das nicht ... wie löst read () das Problem? Die Antwort hat immer noch keine Lesefunktion. Sollen wir den String in ein Objekt mit einer Lesefunktion einfügen?
Zakdances
84
@yourfriendzak genau gelesen, es sind zwei verschiedene Funktionen mit sehr ähnlichen Namen. json.load()Nimmt eine Datei wie ein Objekt mit einer read()Methode, json.loads()nimmt eine Zeichenfolge. Es ist leicht, die "s" am Ende zu übersehen und zu denken, dass sie die gleiche Methode sind.
Joshmaker
4
Dank Joshmakers Kommentar kann json.loads () Zeichenfolgen für JSON-Daten analysieren!
Yu Shen
2
@yourfriendzak Diese Antwort würde Sie darauf hinweisen, dass Sie das mit openerreichen können.
Chaim
1
@MANISHZOPE ssteht für "string". Ich bin damit einverstanden, dass die Standardbibliothek insgesamt einige schwerwiegende Probleme mit der Benennung von Dingen hat, und dies ist ein gutes Beispiel dafür, wie sie durcheinander gebracht wird.
Karl Knechtel
13
AttributeError("'str' object has no attribute 'read'",)

Dies bedeutet genau das, was es sagt: Etwas hat versucht, ein .readAttribut für das Objekt zu finden, das Sie ihm gegeben haben, und Sie haben ihm ein Objekt vom Typ gegeben str(dh Sie haben ihm eine Zeichenfolge gegeben).

Der Fehler ist hier aufgetreten:

json.load (jsonofabitch)['data']['children']

Nun, Sie suchen readnirgendwo, also muss es in der von json.loadIhnen aufgerufenen Funktion geschehen (wie durch den vollständigen Traceback angezeigt). Das liegt daran , dass Sie json.loadversuchen, .readdas zu tun, was Sie ihm gegeben haben, aber Sie haben es gegeben jsonofabitch, das derzeit eine Zeichenfolge benennt (die Sie durch Aufrufen .readvon erstellt haben response).

Lösung: Rufen .readSie sich nicht an; Die Funktion wird dies tun und erwartet, dass Sie es responsedirekt geben, damit es dies tun kann.

Sie hätten dies auch herausfinden können, indem Sie die integrierte Python-Dokumentation für die Funktion (try help(json.load)oder für das gesamte Modul (try help(json))) gelesen oder die Dokumentation für diese Funktionen unter http://docs.python.org überprüft haben .

Karl Knechtel
quelle
So nannte es OP. Ich bin immer am Zaun darüber, ob ich solche Identifikationsnamen ändern oder beibehalten soll, wenn ich anderen helfe. : /
Karl Knechtel
Oh, du hast recht, ich habe es
überflogen
12

Wenn Sie einen Python-Fehler wie diesen erhalten:

AttributeError: 'str' object has no attribute 'some_method'

Sie haben Ihr Objekt wahrscheinlich versehentlich vergiftet, indem Sie Ihr Objekt mit einer Zeichenfolge überschrieben haben.

So reproduzieren Sie diesen Fehler in Python mit ein paar Codezeilen:

#!/usr/bin/env python
import json
def foobar(json):
    msg = json.loads(json)

foobar('{"batman": "yes"}')

Führen Sie es aus, das druckt:

AttributeError: 'str' object has no attribute 'loads'

Aber ändern Sie den Namen des Variablennamens, und es funktioniert gut:

#!/usr/bin/env python
import json
def foobar(jsonstring):
    msg = json.loads(jsonstring)

foobar('{"batman": "yes"}')

Dieser Fehler wird verursacht, wenn Sie versucht haben, eine Methode innerhalb einer Zeichenfolge auszuführen. String hat einige Methoden, aber nicht die, die Sie aufrufen. Versuchen Sie also nicht mehr, eine Methode aufzurufen, die String nicht definiert, und suchen Sie, wo Sie Ihr Objekt vergiftet haben.

Eric Leschinski
quelle
6

Ok, das ist aber ein alter Thread. Ich hatte das gleiche Problem, mein Problem war, dass ich json.loadstattdessen verwendet habejson.loads

Auf diese Weise hat json kein Problem mit dem Laden eines Wörterbuchs.

Offizielle Dokumentation

json.load - Deserialisieren Sie fp (eine .read () - unterstützende Textdatei oder Binärdatei, die ein JSON-Dokument enthält) mithilfe dieser Konvertierungstabelle in ein Python-Objekt.

json.loads - Deserialisieren Sie s (eine Str-, Byte- oder Bytearray-Instanz, die ein JSON-Dokument enthält) mithilfe dieser Konvertierungstabelle in ein Python-Objekt.

JohnyMSF
quelle
3

Sie müssen zuerst die Datei öffnen. Das funktioniert nicht:

json_file = json.load('test.json')

Aber das funktioniert:

f = open('test.json')
json_file = json.load(f)
Richard Liang
quelle
1
Ich habe den Fehler in der Frage gefunden, als ich versucht habe, eine Datei anstelle einer Anforderungsantwort in der Frage zu öffnen. Im Backend behandelt json beide eindeutig ähnlich, und diese Antwort hat mir geholfen. Klar eine Gegenstimme wert.
Nitin Khanna