
The error Attributeerror: 'str' object has no attribute 'read' usually occurs when you are trying to read the content of a file in Python.
The stack trace of this error is as follows:
Traceback (most recent call last):
  File ...
    data = file.read()
AttributeError: 'str' object has no attribute 'read'
The read() function is a part of the built-in io module that’s used to read the content of a file. Calling the function from a string will cause this error.
The following examples show when this error occurs and how you can resolve it.
1. Calling read on a string object
Suppose you try to read the content of a file as follows:
file_location = "output.txt"
data = file_location.read()
Because the file_location variable is a string, calling the read() function will cause the error.
To fix this, you need to open the file first, then call the read() from the returned file object:
file_location = "output.txt"
with open(file_location, "r") as file:
    data = file.read()
    print(data)
You don’t receive an error because the read() function is being called from the file object instead of the string file_location.
2. Passing a string to json.load()
The json.load() method in Python is used to read the content of a JSON file, but you still need to open the file first with open().
Suppose you have a JSON file named data.json and you load it as follows:
import json
data = json.load("data.json")  # ❌
You’ll get the same 'str' object has no attribute 'read' error.
To avoid the error, you need to open() the file first like this:
import json
with open("data.json", 'r') as file:
    data = json.load(file)
    print(data)
After opening the file, you then pass the file object to the json.load() method.
If you already have a JSON string, then use json.loads() to decode that string:
import json
json_str = '{"name": "Nathan"}'
json_obj = json.loads(json_str)
print(json_obj["name"])  # Nathan
The json.load() method is used to decode a file content into a JSON object, while json.loads() decode a string into a JSON object.
3. Calling read on urllib module
This error may occur when you mistakenly call the read() function from a url string when using the urllib module.
Suppose you try to read the content of a website as follows:
import urllib.request
url = 'https://apple.com/'
data = url.read()  # ❌
# AttributeError: 'str' object has no attribute 'read'
The correct way to read a website’s content is to first open the url with urllib.request.urlopen() like this:
import urllib.request
with urllib.request.urlopen('https://apple.com/') as file:
    data = file.read()
    print(data)
You can look at the print() function output to verify the fix.
Conclusion
To conclude, the error Attributeerror: 'str' object has no attribute 'read' happens when the read() function is called from a string instead of a file object.
Most likely, you’ve misunderstood how to access and read a file object, such as when calling json.load() or reading from a URL. The examples above should help you fix this error.
I hope this article was helpful. Happy coding! 😉