AttributeError (“o objeto 'str' não tem atributo 'read'”)


134

No Python, estou recebendo um erro:

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

Dado código 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']

O que esse erro significa e o que eu fiz para causá-lo?


187
Eu gosto do jsonofabitchnome da variável
Mon Calamari

6
Haha! O que é esse "jsonofabitch"? : D
Bahadir Tasdemir

13
Parece que os moderadores de Stackoverflow tem um senso de humor, para uma mudança ...
Pepito Fernandez

6
2019 e isso ainda é engraçado: P
Rishav

1
Na verdade, fez o meu dia, obrigado do futuro :)
Pesche Helfer

Respostas:


187

O problema é que, para json.loadvocê, deve passar um arquivo como objeto com uma readfunção definida. Então você usa json.load(response)ou json.loads(response.read()).


3
Eu não entendo isso ... como o read () resolve o problema? A resposta ainda não tem uma função de leitura. Devemos colocar a string em algum objeto com uma função de leitura?
Zakdances 11/08

85
@yourfriendzak leia atentamente, são duas funções diferentes com nomes muito semelhantes. json.load()pega um arquivo como objeto com um read()método, json.loads()pega uma string. É fácil perder os "s" no final e pensar que eles são o mesmo método.
Joshmaker

4
Graças ao comentário de Joshmaker, json.loads () pode analisar a cadeia de caracteres para dados JSON!
Yu Shen

2
@yourfriendzak Esta resposta indica que openvocê pode conseguir isso.
chaim

1
@MANISHZOPE ssignifica "string". Concordo que a biblioteca padrão tem alguns problemas sérios no geral com a maneira como as coisas são nomeadas, e este é um bom exemplo de como é confuso.
Karl Knechtel

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

Isso significa exatamente o que diz: algo tentou encontrar um .readatributo no objeto que você deu e um objeto do tipo str(ou seja, você deu uma string).

O erro ocorreu aqui:

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

Bem, você não está procurando readnenhum lugar, portanto, isso deve acontecer na json.loadfunção que você chamou (como indicado pelo rastreamento completo). Isso é porque json.loadestá tentando .reada coisa que você deu, mas você deu jsonofabitch, que atualmente nomeia uma string (que você criou chamando .readno response).

Solução: não chame .reada si mesmo; a função fará isso e espera que você dê o responsediretamente para que ele possa fazê-lo.

Você também pode ter descoberto isso lendo a documentação interna do Python para a função (try help(json.load)ou para todo o módulo (try help(json))) ou verificando a documentação dessas funções em http://docs.python.org .


Foi assim que o OP chamou. Estou sempre em dúvida sobre mudar ou preservar esses nomes de identificador ao ajudar outras pessoas. : /
Karl Knechtel

Oh, você está certo, eu desnatado isso ... Eu não estava reclamando, embora :)
Andrea Ligios

12

Se você receber um erro python como este:

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

Você provavelmente envenenou seu objeto acidentalmente substituindo-o por uma string.

Como reproduzir esse erro em python com algumas linhas de código:

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

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

Execute-o, que imprime:

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

Mas mude o nome do nome da variável e ele funciona bem:

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

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

Este erro é causado quando você tenta executar um método dentro de uma string. String possui alguns métodos, mas não o que você está chamando. Portanto, pare de tentar invocar um método que String não define e comece a procurar onde você envenenou seu objeto.


7

Ok, este é um tópico antigo, mas. Eu tive um mesmo problema, meu problema foi usar em json.loadvez dejson.loads

Dessa forma, o json não tem nenhum problema em carregar qualquer tipo de dicionário.

Documentação oficial

json.load - Desserializa o fp (a .read () - suportando arquivo de texto ou arquivo binário que contém um documento JSON) para um objeto Python usando esta tabela de conversão.

json.loads - desserializa s (uma instância de str, bytes ou bytearray que contém um documento JSON) para um objeto Python usando esta tabela de conversão.


5

Você precisa abrir o arquivo primeiro. Isso não funciona:

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

Mas isso funciona:

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

2
Encontrei o erro na pergunta ao tentar abrir um arquivo em vez de uma resposta de solicitação na pergunta. Claramente, no back-end, o json está tratando os dois da mesma forma e, portanto, essa resposta me ajudou. Claramente vale a pena votar.
Nitin Khanna
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.