AttributeError (l'oggetto "'str' non ha attributi 'read'”)


134

In Python ricevo un errore:

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

Dato codice python:

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']

Cosa significa questo errore e cosa ho fatto per causarlo?


188
Mi piace il jsonofabitchnome della variabile.
Mon Calamari,

6
Haha! Cos'è quel "jsonofabitch"? : D
Bahadir Tasdemir

13
Sembra che i moderatori di Stackoverflow abbiano un senso dell'umorismo, per cambiare ...
Pepito Fernandez,

6
2019 e questo è ancora divertente: P
Rishav

1
Anzi, ha reso la mia giornata, grazie dal futuro :)
Pesche Helfer,

Risposte:


187

Il problema è che per json.loadte dovresti passare un file come oggetto con una readfunzione definita. Quindi o usi json.load(response)o json.loads(response.read()).


3
Non capisco questo ... come fa il read () a risolvere il problema? La risposta non ha ancora una funzione di lettura. Dovremmo mettere la stringa in qualche oggetto con una funzione di lettura?
zakdances,

85
@yourfriendzak ha letto da vicino, sono due diverse funzioni con nomi molto simili. json.load()prende un file come oggetto con un read()metodo, json.loads()prende una stringa. Alla fine è facile perdere la "s" e pensare che siano lo stesso metodo.
Joshmaker,

4
Grazie al commento di Joshmaker, json.loads () può analizzare la stringa per i dati JSON!
Yu Shen,

2
@yourfriendzak Questa risposta ti indicherebbe che con opente puoi raggiungerlo.
Chaim

1
@MANISHZOPE ssta per "stringa". Sono d'accordo sul fatto che la libreria standard abbia alcuni problemi seri nel modo in cui le cose vengono nominate, e questo è un buon esempio di come viene incasinato.
Karl Knechtel,

13
AttributeError("'str' object has no attribute 'read'",)

Ciò significa esattamente ciò che dice: qualcosa ha cercato di trovare un .readattributo sull'oggetto che gli hai dato e gli hai dato un oggetto di tipostr (cioè gli hai dato una stringa).

L'errore si è verificato qui:

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

Bene, non stai cercando da readnessuna parte, quindi deve accadere nella json.loadfunzione che hai chiamato (come indicato dal traceback completo). Questo perché json.loadsta provando .readla cosa che gli hai dato, ma tu l'hai dato jsonofabitch, che attualmente chiama una stringa (che hai creato chiamando .readil response).

Soluzione: non chiamarti .read; la funzione lo farà e si aspetta che tu lo dia responsedirettamente in modo che possa farlo.

Potresti anche averlo capito leggendo la documentazione Python integrata per la funzione (provare help(json.load), o per l'intero modulo (provare help(json)), o controllando la documentazione per tali funzioni su http://docs.python.org .


Ecco come lo ha chiamato OP. Sono sempre alla ricerca di se modificare o conservare tali nomi identificativi quando si aiutano gli altri. : /
Karl Knechtel,

Oh, hai ragione, l'ho scremato ... Non mi lamento, però :)
Andrea Ligios,

12

Se ricevi un errore Python come questo:

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

Probabilmente hai avvelenato il tuo oggetto accidentalmente sovrascrivendolo con una stringa.

Come riprodurre questo errore in Python con alcune righe di codice:

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

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

Eseguilo, che stampa:

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

Ma cambia il nome del variablename e funziona benissimo:

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

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

Questo errore si verifica quando si tenta di eseguire un metodo all'interno di una stringa. String ha alcuni metodi, ma non quello che stai invocando. Quindi smetti di provare a invocare un metodo che String non definisce e inizia a cercare dove hai avvelenato il tuo oggetto.


7

Ok, questo è un vecchio thread ma. Ho avuto lo stesso problema, il mio problema è stato usato al json.loadposto dijson.loads

In questo modo, json non ha problemi con il caricamento di qualsiasi tipo di dizionario.

Documentazione ufficiale

json.load - Deserializza fp (a .read () - supporta file di testo o file binario contenente un documento JSON) su un oggetto Python usando questa tabella di conversione.

json.loads - Deserializza s (un'istanza str, byte o bytearray contenente un documento JSON) su un oggetto Python usando questa tabella di conversione.


5

Devi prima aprire il file. Questo non funziona:

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

Ma questo funziona:

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

2
Ho trovato l'errore nella domanda durante il tentativo di aprire un file anziché una risposta alla richiesta nella domanda. Chiaramente, nel backend, Json sta trattando entrambi allo stesso modo, e quindi questa risposta mi ha aiutato. Chiaramente merita un voto.
Nitin Khanna,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.