AttributeError ("str" ​​об'єкт не має атрибута "read" ")


134

У Python я отримую помилку:

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

Дано код пітона:

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

Що означає ця помилка і що я зробив, щоб її викликати?


187
Мені подобається jsonofabitchім'я змінної.
пн Каламарі

6
Ха-ха! Що це за "jsonofabitch"? : D
Бахадір Тасдемір

13
Здається, що у модераторів Stackoverflow є почуття гумору, на зміну ...
Pepito Fernandez

6
2019 рік, і це все ще смішно: П
Рішав

1
Дійсно, зробив свій день, дякую від майбутнього :)
Пеше Хелфер

Відповіді:


187

Проблема полягає в тому, що для json.loadвас слід передавати файл типу об’єкта з readвизначеною функцією. Отже, або ви використовуєте, json.load(response)або json.loads(response.read()).


3
Я цього не розумію ... як читання () вирішує проблему? Відповідь досі не має функції зчитування. Чи слід ставити рядок у якийсь об'єкт із функцією читання?
zakdances

85
@yourfriendzak читайте уважно, це дві різні функції з дуже схожими назвами. json.load()бере read()метод, схожий на об'єкт, методом, json.loads()бере рядок. Легко пропустити "s" наприкінці і подумати, що вони однаковий метод.
Joshmaker

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 для функції (спробуйте help(json.load), або на весь модуль (спробуйте help(json)), або перевіривши документацію для цих функцій на http://docs.python.org .


Ось так це назвало ОП. Я завжди на огорожі щодо того, чи потрібно змінювати чи зберігати такі ідентифікаційні імена, коли допомагати іншим. : /
Карл

Ой, ти маєш рацію, я прогризав це ... Хоча я не скаржився :)
Andrea Ligios

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'

Але змініть ім'я назви змінної, і вона справно працює:

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

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

Ця помилка виникає при спробі запустити метод у рядку. У рядку є кілька методів, але не той, до якого ви посилаєтесь. Тому перестаньте намагатися викликати метод, який String не визначає, і починайте шукати, де ви отруїли свій об’єкт.


7

Добре, це стара тема, але. У мене була така ж проблема, мою проблему я використовував json.loadзамість цьогоjson.loads

Таким чином, json не має проблем із завантаженням будь-якого словника.

Офіційна документація

json.load - Десеріалізувати fp (a .read () - підтримуючий текстовий файл або двійковий файл, що містить документ JSON) до об’єкта Python, використовуючи цю таблицю перетворення.

json.loads - Десеріалізувати s (str, байти чи екземпляр байтаря, що містить документ JSON) до об'єкта Python, використовуючи цю таблицю перетворення.


5

Спочатку потрібно відкрити файл. Це не працює:

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

Але це працює:

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

2
Я знайшов помилку у питанні під час спроби відкрити файл замість відповіді на запит. Ясна річ, що в бекенді json ставиться і до того ж, і тому ця відповідь мені допомогла. Очевидно, що варто заплатити.
Нітін Ханна
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.