AttributionError (đối tượng 'str' không có thuộc tính 'đọc' ')


133

Trong Python tôi đang gặp lỗi:

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

Cho mã trăn:

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

Lỗi này có nghĩa là gì và tôi đã làm gì để gây ra nó?


187
Tôi thích jsonofabitchtên biến.
Mon Calamari

6
Haha! Cái gì mà "jsonofabitch"? : D
Bahadir Tasdemir

13
Có vẻ như người điều hành Stackoverflow có khiếu hài hước, vì một sự thay đổi ...
Pepito Fernandez

6
2019 và điều này vẫn còn buồn cười: P
Rishav

1
Thật vậy, đã làm cho ngày của tôi, cảm ơn bạn từ tương lai :)
Pesche Helfer

Câu trả lời:


186

Vấn đề là đối với json.loadbạn nên truyền một tệp như đối tượng với readhàm được xác định. Vì vậy, hoặc bạn sử dụng json.load(response)hoặc json.loads(response.read()).


3
Tôi không hiểu điều này ... làm thế nào để đọc () giải quyết vấn đề? Phản hồi vẫn không có chức năng đọc. Chúng ta có nên đặt chuỗi trong một số đối tượng có chức năng đọc không?
zakdances

84
@yourfriendzak đọc kỹ, đó là hai chức năng khác nhau với tên rất giống nhau. json.load()lấy một tệp như đối tượng với một read()phương thức, json.loads()lấy một chuỗi. Thật dễ dàng để bỏ lỡ "s" ở cuối và nghĩ rằng chúng là cùng một phương pháp.
Joshmaker

4
Nhờ nhận xét của Joshmaker, json.loads () có thể phân tích chuỗi cho dữ liệu JSON!
Yu Shen

2
@yourfriendzak Câu trả lời này sẽ cho bạn thấy rằng với openbạn có thể đạt được điều đó.
chaim

1
@MANISHZOPE slà viết tắt của "chuỗi". Tôi đồng ý rằng thư viện tiêu chuẩn có một số vấn đề nghiêm trọng về cách mọi thứ được đặt tên và đây là một ví dụ tốt về cách nó bị rối tung.
Karl Knechtel

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

Điều này có nghĩa chính xác những gì nó nói: một cái gì đó đã cố gắng tìm một .read thuộc tính trên đối tượng mà bạn đã cho nó và bạn đã cho nó một đối tượng thuộc loại str(nghĩa là bạn đã cho nó một chuỗi).

Lỗi xảy ra ở đây:

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

Chà, bạn không tìm kiếm readbất cứ nơi nào, vì vậy nó phải xảy ra trong json.loadchức năng mà bạn đã gọi (như được biểu thị bằng truy nguyên đầy đủ). Đó là bởi vì json.loadđang cố gắng với .readthứ mà bạn đã cho nó, nhưng bạn đã cho nójsonofabitch , hiện đang đặt tên cho một chuỗi (mà bạn đã tạo bằng cách gọi .readtrên response).

Giải pháp: đừng gọi .read cho mình; chức năng sẽ làm điều này và hy vọng bạn cung cấp cho nó responsetrực tiếp để nó có thể làm như vậy.

Bạn cũng có thể đã tìm ra điều này bằng cách đọc tài liệu Python tích hợp cho hàm (thử help(json.load)hoặc cho toàn bộ mô-đun (thử help(json)) hoặc bằng cách kiểm tra tài liệu cho các chức năng đó trên http://docs.python.org .


Đó là những gì OP gọi nó. Tôi luôn luôn ở trên hàng rào về việc thay đổi hoặc giữ nguyên tên định danh đó khi giúp đỡ người khác. : /
Karl Knechtel

Ồ, bạn nói đúng, tôi đã lướt qua nó ... Tuy nhiên, tôi đã không phàn nàn :)
Andrea Ligios

12

Nếu bạn gặp lỗi python như thế này:

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

Bạn có thể đã vô tình đầu độc đối tượng của mình bằng cách ghi đè lên đối tượng của bạn bằng một chuỗi.

Cách tái tạo lỗi này trong python bằng một vài dòng mã:

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

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

Chạy nó, in:

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

Nhưng thay đổi tên của tên tập tin và nó hoạt động tốt:

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

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

Lỗi này xảy ra khi bạn cố chạy một phương thức trong một chuỗi. Chuỗi có một vài phương thức, nhưng không phải là phương thức bạn đang gọi. Vì vậy, hãy ngừng cố gắng gọi một phương thức mà String không xác định và bắt đầu tìm kiếm nơi bạn đã đầu độc đối tượng của mình.


6

Ok, đây là một chủ đề cũ nhưng. Tôi có một vấn đề tương tự, vấn đề của tôi là tôi đã sử dụng json.loadthay vìjson.loads

Bằng cách này, json không có vấn đề với việc tải bất kỳ loại từ điển nào.

Tài liệu chính thức

json.load - Deserialize fp (a .read () - hỗ trợ tệp văn bản hoặc tệp nhị phân chứa tài liệu JSON) cho đối tượng Python bằng bảng chuyển đổi này.

json.loads - Deserialize s (một ví dụ str, byte hoặc bytearray có chứa tài liệu JSON) cho một đối tượng Python sử dụng bảng chuyển đổi này.


3

Bạn cần mở tập tin trước. Điều này không hoạt động:

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

Nhưng điều này hoạt động:

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

1
Tôi đã tìm thấy lỗi trong câu hỏi khi cố gắng mở tệp thay vì phản hồi yêu cầu trong câu hỏi. Rõ ràng, ở phần phụ trợ, json đang đối xử tương tự, và vì vậy câu trả lời này đã giúp tôi. Rõ ràng giá trị một upvote.
Nitin Khanna
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.