Signup/Sign In
Ask Question
Not satisfied by the Answer? Still looking for a better solution?

TypeError: a bytes-like object is required, not 'str' when writing to a file in Python3.5

I've recently migrated to Py 3.5. This code was working properly in Python 2.7:

with open(fname, 'rb') as f:
lines = [x.strip() for x in f.readlines()]

for line in lines:
tmp = line.strip().lower()
if 'some-pattern' in tmp: continue
# ... code

After upgrading to 3.5, I'm getting the:

TypeError: a bytes-like object is required, not 'str'
error on the last line (the pattern search code).

I've tried using the .decode() function on either side of the statement, also tried:

if tmp.find('some-pattern') != -1: continue
- to no avail.

I was able to resolve almost all 2:3 issues quickly, but this little statement is bugging me.
by

3 Answers

Kajalsi45d
you opened the file in binary mode:

with open(fname, 'rb') as f:

This means that all data read from the file is returned as bytes objects, not str. You cannot then use a string in a containment test:

if 'some-pattern' in tmp: continue

You'd have to use a bytes object to test against tmp instead:

if b'some-pattern' in tmp: continue

or open the file as a textfile instead by replacing the 'rb' mode with 'r'.
sandhya6gczb
To open file with open('file_sample.txt', 'rb')* is used. *rb is used to read the file in binary mode. It means the data is read in form of bytes. But the string is used to split byte objects which is wrong.
To solve this add prefix the string with b

split_line = tmp.split(b';') # Added the b prefix

This converts the string to byte, So type matches.
pankajshivnani123
Like it has been already mentioned, you are reading the file in binary mode and then creating a list of bytes. In your following for loop you are comparing string to bytes and that is where the code is failing.

Decoding the bytes while adding to the list should work. The changed code should look as follows:

with open(fname, 'rb') as f:
lines = [x.decode('utf8').strip() for x in f.readlines()]

The bytes type was introduced in Python 3 and that is why your code worked in Python 2. In Python 2 there was no data type for bytes:

>>> s=bytes('hello')
>>> type(s)
<type 'str'>

Login / Signup to Answer the Question.