AttributeError ("objek 'str' tidak memiliki atribut 'baca'")

134

Dalam Python saya mendapatkan kesalahan:

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

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

Apa arti kesalahan ini dan apa yang saya lakukan untuk menyebabkannya?

RobinJ
sumber
187
Saya suka jsonofabitchnama variabel.
Mon Calamari
6
Ha ha! Apa itu "jsonofabitch"? : D
Bahadir Tasdemir
13
Sepertinya para moderator Stackoverflow memiliki selera humor, untuk sebuah perubahan ...
Pepito Fernandez
6
2019 dan ini masih lucu: P
Rishav
1
Memang, buat hari saya, terima kasih dari masa depan :)
Pesche Helfer

Jawaban:

187

Masalahnya adalah bahwa json.loadAnda harus meneruskan file seperti objek dengan readfungsi yang ditentukan. Jadi apakah Anda menggunakan json.load(response)atau json.loads(response.read()).

kosii
sumber
3
Saya tidak mengerti ini ... bagaimana melakukan read () menyelesaikan masalah? Responsnya masih belum memiliki fungsi baca. Apakah kita seharusnya meletakkan string di beberapa objek dengan fungsi baca?
zakdances
85
@yourfriendzak membaca dengan cermat, itu adalah dua fungsi yang berbeda dengan nama yang sangat mirip. json.load()mengambil file seperti objek dengan read()metode, json.loads()mengambil string. Sangat mudah untuk melewatkan "s" di akhir dan berpikir mereka adalah metode yang sama.
Joshmaker
4
Berkat komentar Joshmaker, json.loads () dapat mengurai string untuk data JSON!
Yu Shen
2
@yourfriendzak Jawaban ini akan menunjukkan kepada Anda bahwa dengan openAnda dapat mencapainya.
chaim
1
@MANISHZOPE ssingkatan dari "string". Saya setuju bahwa perpustakaan standar memiliki beberapa masalah serius secara keseluruhan dengan bagaimana hal-hal itu dinamai, dan ini adalah contoh yang baik tentang bagaimana itu menjadi kacau.
Karl Knechtel
13
AttributeError("'str' object has no attribute 'read'",)

Ini berarti persis seperti yang dikatakannya: sesuatu mencoba menemukan .readatribut pada objek yang Anda berikan, dan Anda memberinya objek tipe str(yaitu, Anda memberinya string).

Kesalahan terjadi di sini:

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

Nah, Anda tidak mencari di readmana pun, jadi itu harus terjadi pada json.loadfungsi yang Anda panggil (seperti yang ditunjukkan oleh traceback penuh). Itu karena json.loadsedang mencoba .readhal yang Anda berikan, tetapi Anda memberikannya jsonofabitch, yang saat ini menamai string (yang Anda buat dengan memanggil .readpada response).

Solusi: jangan menyebut .readdiri Anda; fungsi akan melakukan ini, dan mengharapkan Anda untuk memberikannya secara responselangsung sehingga dapat melakukannya.

Anda juga bisa mengetahuinya dengan membaca dokumentasi Python bawaan untuk fungsi (coba help(json.load), atau untuk seluruh modul (coba help(json)), atau dengan memeriksa dokumentasi untuk fungsi-fungsi tersebut di http://docs.python.org .

Karl Knechtel
sumber
Itulah yang disebut OP. Saya selalu di pagar tentang apakah akan mengubah atau mempertahankan nama pengenal seperti ketika membantu orang lain. : /
Karl Knechtel
Oh, kau benar, aku sudah menekanya ... Aku tidak mengeluh, :)
Andrea Ligios
12

Jika Anda mendapatkan kesalahan python seperti ini:

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

Anda mungkin meracuni objek Anda secara tidak sengaja dengan menimpa objek Anda dengan tali.

Cara mereproduksi kesalahan ini dalam python dengan beberapa baris kode:

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

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

Jalankan, yang mencetak:

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

Tetapi ubah nama variablename, dan itu berfungsi dengan baik:

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

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

Kesalahan ini disebabkan ketika Anda mencoba menjalankan metode dalam string. String memiliki beberapa metode, tetapi bukan metode yang Anda gunakan. Jadi berhentilah mencoba memanggil metode yang tidak didefinisikan oleh String dan mulailah mencari tempat Anda meracuni objek Anda.

Eric Leschinski
sumber
7

Ok, ini utas lama tapi. Saya memiliki masalah yang sama, masalah saya yang saya gunakan json.loadbukanjson.loads

Dengan cara ini, json tidak memiliki masalah dengan memuat kamus apa pun.

Dokumentasi resmi

json.load - Deserialize fp (a .read () - file teks pendukung atau file biner yang berisi dokumen JSON) ke objek Python menggunakan tabel konversi ini.

json.loads - Deserialize s (str, byte atau instance bytearray yang berisi dokumen JSON) ke objek Python menggunakan tabel konversi ini.

JohnyMSF
sumber
5

Anda harus membuka file terlebih dahulu. Ini tidak berfungsi:

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

Tapi ini berhasil:

f = open('test.json')
json_file = json.load(f)
Richard Liang
sumber
2
Saya menemukan kesalahan dalam pertanyaan ketika mencoba membuka file alih-alih respons permintaan dalam pertanyaan. Jelas, di backend, json memperlakukan keduanya dengan cara yang sama, dan jawaban ini membantu saya. Jelas layak mendapat upvote.
Nitin Khanna