This error typically occurs when you try to read the string pointing to the path of a file instead of a file object. To solve this error, you should use the appropriate method for reading the path of a file or reading a file object.
Generally, when reading in an object using a function, check to see what data type the function expects in its documentation.
This tutorial will go through the error in detail and solve it with code examples.
Table of contents
AttributeError: ‘str’ object has no attribute ‘read’
AttributeError occurs in a Python program when we try to access an attribute (method or property) that does not exist for a particular object. The part “‘str’ object has no attribute ‘read’” tells us that the string object does not have the attribute read(). The read() method belongs to the File data type and returns the specified number of bytes from the file. The syntax of the read method is as follows:
file.read()
Parameters:
- size: Optional. The number of bytes to return. The default is -1, which means the whole file.
Let’s look at an example of using the read() method to read a file. The text file is ‘test.txt’ and has the following contents:
test
The code is as follows:
f = open('test.txt', 'r') print(type(f)) print(f.read())
The open() function opens a file and returns it as a file object. The parameter ‘r’ sets the function to read. We also print the type of f
object to verify it is a file object. Let’s run the code to see the result:
<class '_io.TextIOWrapper'> test
TextIOWrapper object is a text stream that allows us to access the file’s contents as a list of strings.
Let’s see what happens when we try to call read() on a string representing the filename:
f = 'test.txt' print(type(f)) print(f.read())
<class 'str'> --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-7-d6f605ca887b> in <module> 1 f = 'test.txt' 2 print(type(f)) ----> 3 print(f.read()) AttributeError: 'str' object has no attribute 'read'
We raise the AttributeError because the read() method is only suitable for File objects. We cannot read a file by calling read() on the filename string.
Example: Using json.load()
The error commonly occurs when using the json
library to read a JSON string instead of a JSON file object. There are two different methods in the json
library:
json.load()
: Deserializes a text or binary file containing a JSON document to a Python objectjson.loads()
: Deserializes a str, bytes, or bytearray instance containing a JSON document to a Python object
If you have a JSON string, you must use json.loads() if you use json.load() instead, you will raise the AttributeError.
Let’s look at an example where we want to make an HTTP POST request to httpbin. We will read a string into the program using open() and create a JSON payload to post to the specified URL.
The text file star_wars.txt
contains the following dictionary:
{"id": 1, "name": "Anakin", "passion": "podracing"}
The code to load and POST the payload is as follows:
import requests import json url = "https://httpbin.org/post" headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } infile = open('star_wars.txt', 'r') string = infile.readline() payload = json.load(string) response = requests.post(url, json=payload, no sheaders=headers) print("Status code: ", response.status_code) print("Response as JSON: ", response.json())
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-1-fae504fd2214> in <module> 10 string = infile.readline() 11 ---> 12 payload = json.load(string) 13 14 x = request.post(url, json=payload, params=params, headers=headers) ~/opt/anaconda3/lib/python3.8/json/__init__.py in load(fp, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 291 kwarg; otherwise ``JSONDecoder`` is used. 292 """ --> 293 return loads(fp.read(), 294 cls=cls, object_hook=object_hook, 295 parse_float=parse_float, parse_int=parse_int, AttributeError: 'str' object has no attribute 'read'
The error occurs because the json.load() method expects a File object as a parameter but instead receives a string.
Solution
We need to use json.loads() to solve this error. Let’s look at the revised code:
import requests import json url = "https://httpbin.org/post" headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } infile = open('star_wars.txt', 'r') string = infile.readline() payload = json.loads(string) response = requests.post(url, json=payload, headers=headers) print("Status code: ", response.status_code) print("Response as JSON: ", response.json())
Let’s run the code to get the result:
Status code: 200 Response as JSON: {'args': {'priority': 'normal'}, 'data': '{"id": 1, "name": "Anakin", "passion": "podracing"}', 'files': {}, 'form': {}, 'headers': {'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate, br', 'Content-Length': '51', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-622bd6f5-3122393306eab3cd6df2c488'}, 'json': {'id': 1, 'name': 'Anakin', 'passion': 'podracing'}, 'origin': '90.206.95.191', 'url': 'https://httpbin.org/post?priority=normal'}
The status code 200 tells us we successfully made the HTTP request and retrieved the response.
Summary
Congratulations on reading to the end of this tutorial! The AttributeError: ‘str’ object has no attribute ‘read’ occurs when you call the read()
method on a string object. You may encounter this when using the json library as there are two distinct methods load() for File objects and loads() string and byte objects. Ensure that you use the json.loads() method when you want to access the contents JSON string.
For further reading on AttributeErrors, go to the articles:
- How to Solve Python AttributeError: ‘str’ object has no attribute ‘len’
- How to Solve Python AttributeError: ‘tuple’ object has no attribute ‘append’
- How to Solve Python AttributeError: ‘float’ object has no attribute ’round’
- How to Solve Python AttributeError: ‘str’ object has no attribute ‘pop’
- How to Solve Python AttributeError: ‘str’ object has no attribute ‘close’
To learn more about Python for data science and machine learning, go to the online courses page on Python for the most comprehensive courses available.
Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.