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

ข้อผิดพลาดนี้หมายความว่าอย่างไรและฉันทำอะไรเพื่อให้เกิดข้อผิดพลาดนี้


191
ฉันชอบjsonofabitchชื่อตัวแปร
Mon Calamari

6
ฮ่าฮ่า! "jsonofabitch" นั้นคืออะไร? : D
Bahadir Tasdemir

13
ดูเหมือนว่าผู้ดูแลของ Stackoverflow จะมีอารมณ์ขันสำหรับการเปลี่ยนแปลง ...
Pepito Fernandez

6
2019 และนี่ก็ยังตลกอยู่: P
Rishav

1
แน่นอนทำให้วันของฉันขอบคุณจากอนาคต :)
Pesche Helfer

คำตอบ:


187

ปัญหาคือjson.loadคุณควรส่งไฟล์เช่น object ที่มีreadฟังก์ชันกำหนดไว้ ดังนั้นคุณใช้json.load(response)หรือjson.loads(response.read()).


3
ฉันไม่เข้าใจสิ่งนี้ ... การอ่าน () จะแก้ปัญหาได้อย่างไร การตอบสนองยังคงไม่มีฟังก์ชันอ่าน เราควรใส่สตริงในวัตถุบางอย่างด้วยฟังก์ชันอ่านหรือไม่?
zakdances

87
@yourfriendzak อ่านอย่างใกล้ชิดมันเป็นสองฟังก์ชั่นที่แตกต่างกันที่มีชื่อคล้ายกันมาก json.load()ใช้ไฟล์เช่น object ด้วยread()วิธีการjson.loads()รับสตริง ง่ายมากที่จะพลาด "s" ในตอนท้ายและคิดว่าเป็นวิธีการเดียวกัน
Joshmaker

4
ขอบคุณความคิดเห็นของ Joshmaker json.loads () สามารถแยกวิเคราะห์สตริงสำหรับข้อมูล JSON ได้!
Yu Shen

2
@yourfriendzak คำตอบนี้จะชี้ให้คุณเห็นว่าopenคุณสามารถบรรลุสิ่งนั้นได้ด้วย
chaim

1
@MANISHZOPE sย่อมาจาก "string" ฉันยอมรับว่าไลบรารีมาตรฐานมีปัญหาร้ายแรงโดยรวมเกี่ยวกับวิธีการตั้งชื่อสิ่งต่างๆและนี่เป็นตัวอย่างที่ดีในการทำให้เกิดความสับสน
Karl Knechtel

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โดยตรงเพื่อให้สามารถทำได้

นอกจากนี้คุณยังจะได้คิดออกนี้โดยการอ่านในตัวเอกสารหลามสำหรับฟังก์ชั่น (ลองhelp(json.load)หรือสำหรับโมดูลทั้งหมด (ลองhelp(json)) หรือโดยการตรวจสอบเอกสารสำหรับฟังก์ชั่นที่อยู่บนhttp://docs.python.org


นั่นคือสิ่งที่ OP เรียกมัน ฉันมักจะอยู่ในรั้วเสมอว่าจะเปลี่ยนหรือสงวนชื่อตัวระบุดังกล่าวไว้เมื่อช่วยเหลือผู้อื่น : /
Karl Knechtel

โอ้คุณพูดถูกฉันอ่านมัน ... ฉันไม่ได้บ่น :)
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'

แต่เปลี่ยนชื่อของ variablename และใช้งานได้ดี:

#!/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 - Deserialize fp (a .read () - รองรับไฟล์ข้อความหรือไฟล์ไบนารีที่มีเอกสาร JSON) ไปยังวัตถุ Python โดยใช้ตารางการแปลงนี้

json.loads - Deserialize s (อินสแตนซ์ str, bytes หรือ bytearray ที่มีเอกสาร JSON) ไปยังออบเจ็กต์ Python โดยใช้ตารางการแปลงนี้


5

คุณต้องเปิดไฟล์ก่อน สิ่งนี้ใช้ไม่ได้:

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

แต่ใช้งานได้:

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

2
ฉันพบข้อผิดพลาดในคำถามเมื่อพยายามเปิดไฟล์แทนการตอบกลับคำขอในคำถาม เห็นได้ชัดว่าที่แบ็กเอนด์ json ปฏิบัติต่อทั้งสองอย่างในทำนองเดียวกันคำตอบนี้ช่วยฉัน เห็นได้ชัดว่ามีมูลค่าการโหวตเพิ่มขึ้น
Nitin Khanna
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.