TypeError: a bytes-like object is required, not ‘str’ when writing to a file in Python3

Posted on

Solving problem is about exposing yourself to as many situations as possible like TypeError: a bytes-like object is required, not ‘str’ when writing to a file in Python3 and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about TypeError: a bytes-like object is required, not ‘str’ when writing to a file in Python3, which can be followed any time. Take easy to follow this discuss.

TypeError: a bytes-like object is required, not ‘str’ when writing to a file in Python3

I’ve very 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.

Asked By: masroore

||

Answer #1:

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

Answered By: Martijn Pieters

Answer #2:

You can encode your string by using .encode()

Example:

'Hello World'.encode()
Answered By: theofpa

Answer #3:

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'>
Answered By: Suresh

Answer #4:

You have to change from wb to w:

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'wb'))
    self.myCsv.writerow(['title', 'link'])

to

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'w'))
    self.myCsv.writerow(['title', 'link'])

After changing this, the error disappears, but you can’t write to the file (in my case). So after all, I don’t have an answer?

Source: How to remove ^M

Changing to ‘rb’ brings me the other error: io.UnsupportedOperation: write

Answered By: meck373

Answer #5:

for this small example:

import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0nn')
while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ) :
        break
    print (data);
mysock.close()

adding the “b” before
‘GET http://www.py4inf.com/code/romeo.txt HTTP/1.0nn’
solved my problem

Answered By: starter

Answer #6:

Use encode() function along with hardcoded String value given in a single quote.

Ex:

file.write(answers[i] + 'n'.encode())

OR

line.split(' +++$+++ '.encode())
Answered By: Shiv Buyya

Answer #7:

You opened the file in binary mode:

The following code will throw
a TypeError: a bytes-like object is required, not ‘str’.

for line in lines:
    print(type(line))# <class 'bytes'>
    if 'substring' in line:
       print('success')

The following code will work – you have to use the decode() function:

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')
Answered By: Matan Hugi

Answer #8:

why not try opening your file as text?

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

Additionally here is a link for python 3.x on the official page:
https://docs.python.org/3/library/io.html
And this is the open function: https://docs.python.org/3/library/functions.html#open

If you are really trying to handle it as a binary then consider encoding your string.

Answered By: Fernando D Jaime

Leave a Reply

Your email address will not be published.