AttributeError («объект« str »не имеет атрибута« read »»)

134

В Python я получаю сообщение об ошибке:

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

Данный код 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']

Что означает эта ошибка и что я сделал, чтобы вызвать ее?

RobinJ
источник
188
Мне нравится jsonofabitchимя переменной.
Пн Calamari
6
Ха - ха! Что это за "jsonofabitch"? : D
Бахадир Тасдемир
13
Похоже, у модераторов Stackoverflow есть чувство юмора, для разнообразия ...
Pepito Fernandez
6
2019 и это все еще смешно: P
Rishav
1
Действительно, сделал мой день, спасибо от будущего :)
Pesche Helfer

Ответы:

187

Проблема в том, что json.loadвам нужно передать файл, подобный объекту с определенной readфункцией. Так что либо вы используете, json.load(response)либо json.loads(response.read()).

kosii
источник
3
Я не понимаю этого ... как решение read () решает проблему? Ответ по-прежнему не имеет функции чтения. Мы должны поместить строку в некоторый объект с функцией чтения?
Закданс
85
@yourfriendzak читай внимательно, это две разные функции с очень похожими названиями. json.load()принимает файл как объект с read()методом, json.loads()принимает строку. В конце легко пропустить букву «с» и подумать, что это один и тот же метод.
Джошмейкер
4
Благодаря комментарию Joshmaker, json.loads () может анализировать строку для данных JSON!
Ю Шен
2
@yourfriendzak Этот ответ укажет вам, что openвы можете достичь этого.
Хаим
1
@MANISHZOPE sозначает "строка". Я согласен, что у стандартной библиотеки есть некоторые серьезные проблемы с тем, как называются вещи, и это хороший пример того, как она испортилась.
Карл Кнехтель
13
AttributeError("'str' object has no attribute 'read'",)

Это означает именно то, что написано: что-то пыталось найти .readатрибут объекта, который вы ему дали, и вы дали ему объект типа str(то есть вы дали ему строку).

Ошибка произошла здесь:

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

Ну, вы readнигде не ищите , поэтому это должно происходить в json.loadвызванной вами функции (как указано в полной трассировке). Это происходит потому , что json.loadпытается .readвещь , что вы дали, но вы дали jsonofabitch, которые в настоящее время имена строка (которую вы создали, позвонив .readна response).

Решение: не называйте .readсебя; функция сделает это, и ожидает, что вы передадите ее responseнапрямую, чтобы она могла это сделать.

Вы могли бы также выяснить это, прочитав встроенную документацию Python для функции (try help(json.load)или для всего модуля (try help(json))), или проверив документацию для этих функций на http://docs.python.org .

Карл Кнехтель
источник
Это то, что ОП назвал это. Я всегда на грани того, стоит ли менять или сохранять такие имена идентификаторов, помогая другим. : /
Карл
О, вы правы, я снял это ... Я не жаловался, хотя :)
Андреа Лиджиос
12

Если вы получаете ошибку Python, как это:

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

Вы вероятно отравили свой объект случайно, перезаписав свой объект строкой.

Как воспроизвести эту ошибку в python с помощью нескольких строк кода:

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

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

Запустите его, который печатает:

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

Но измените имя переменной name, и она отлично работает:

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

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

Эта ошибка возникает, когда вы пытались запустить метод в строке. String имеет несколько методов, но не тот, который вы вызываете. Так что перестаньте пытаться вызвать метод, который String не определяет, и начните искать, где вы отравили свой объект.

Эрик Лещинский
источник
7

Хорошо, это старая ветка, но. У меня была такая же проблема, моя проблема заключалась в том, что я использовал json.loadвместоjson.loads

Таким образом, у json нет проблем с загрузкой любого словаря.

Официальная документация

json.load - десериализует fp (.read () - вспомогательный текстовый файл или двоичный файл, содержащий документ JSON) в объект Python с использованием этой таблицы преобразования.

json.loads - десериализует s (экземпляр str, bytes или bytearray, содержащий документ JSON) в объект Python с использованием этой таблицы преобразования.

JohnyMSF
источник
5

Сначала вам нужно открыть файл. Это не работает:

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

Но это работает:

f = open('test.json')
json_file = json.load(f)
Ричард Лян
источник
2
Я обнаружил ошибку в вопросе при попытке открыть файл вместо ответа на запрос в вопросе. Очевидно, что на бэкэнде json обрабатывает и то и другое одинаково, и поэтому этот ответ мне помог. Очевидно, что стоит проголосовать за.
Нитин Ханна