I am trying to write python 2/3 compatible code to write strings to csv file object. This code:
line_as_list = [line.encode() for line in line_as_list] writer_file = io.BytesIO() writer = csv.writer(writer_file, dialect=dialect, delimiter=self.delimiter) for line in line_as_list: assert isinstance(line,bytes) writer.writerow(line)
Gives this error on Python3:
> writer.writerow(line) E TypeError: a bytes-like object is required, not 'str'
But assert has no problem with the type, so why is csv
creating an error?
Can't I use BytesIO
only for both Python 2 and 3? Where is the problem here?
Writing CSV files Using csv. To write to a CSV file in Python, we can use the csv. writer() function. The csv. writer() function returns a writer object that converts the user's data into a delimited string.
Python io module allows us to manage the file-related input and output operations. The advantage of using the IO module is that the classes and functions available allows us to extend the functionality to enable writing to the Unicode data.
In Python3 csv.writer
expects a file-like object opened in text mode. In Python2, csv.writer
expects a file-like object opened in binary mode.
Therefore, in Python3, use io.StringIO
, while in Python2 use io.BytesIO
:
import io import csv import sys PY3 = sys.version_info[0] == 3 line_as_list = [u'foo', u'bar'] encoding = 'utf-8' if PY3: writer_file = io.StringIO() else: writer_file = io.BytesIO() line_as_list = [line.encode(encoding) for line in line_as_list] writer = csv.writer(writer_file, dialect='excel', delimiter=',') writer.writerow(line_as_list) content = writer_file.getvalue() if PY3: content = content.encode(encoding) print(type(content)) print(repr(content))
In Python3 the code above prints
<class 'bytes'> b'foo,bar\r\n'
In Python2 the code above prints
<type 'str'> 'foo,bar\r\n'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With