Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing to io.BytesIO in csv fails in python3

Tags:

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?

like image 765
goelakash Avatar asked Jun 22 '16 16:06

goelakash


People also ask

Can you write directly to a csv file in Python?

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.

What is io BytesIO in Python?

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.


1 Answers

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' 
like image 180
unutbu Avatar answered Oct 20 '22 04:10

unutbu