2016-06-22 22 views
8

Csv dosya nesnesine dizeleri yazmak için python 2/3 uyumlu kodu yazmaya çalışıyorum. Bu kod:csv'de io.BytesIO'ya yazı yazmak python3'te hata veriyor

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) 

Python3 bu hatayı verir:

>   writer.writerow(line) 
E   TypeError: a bytes-like object is required, not 'str' 

Ama tip bir problemi yok iddia, neden csv bir hata yaratıyor?

BytesIO sadece Python 2 ve 3 için kullanamaz mıyım? Burada sorun nerede?

+0

@tdelaney Demek istediğim StringIO ve BytesIO'nun kaynak metin için aynı gösterimi (muhtemelen utf-8'de) vereceğinden emin değilim. Bu yüzden aynı çıktı nesne türünü kullanmaya çalışıyorum. – goelakash

cevap

8

Python3'te csv.writer, metin modunda açılan dosya benzeri bir nesne olmasını bekler. Python2'de csv.writer, ikili modda açılan dosya benzeri bir nesne olmasını bekler. Python2 içinde io.BytesIO kullanırken

Bu nedenle, Python3 içinde, io.StringIO kullanımı: Python3 olarak baskı yukarıdaki kodu

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)) 

Python2 olarak

<class 'bytes'> 
b'foo,bar\r\n' 

baskı Yukarıdaki kod

<type 'str'> 
'foo,bar\r\n' 
+0

Bu iyi bir çözümdür, ancak str * * bayt biçimi olduğunda hatanın 'bayt' için neden hata istediği hakkında bir fikriniz var mı? – goelakash

+0

"BytesIO" nesnesinden hata geldiğini düşünüyorum - bayt beklediğinde "str" ​​iletildiğinden şikayet ediyor. Python3'te bir "str" ​​bir "byte formatı" değildir. Bir unicode 'str 'kod noktaları dizisidir. – unutbu

+0

Ama bir str.encode() nesnesini, etkin bir bayt nesnesi geçirdim. O zaman sorun nerede? Bu hata, 'str''nın geçmediğini, (sadece Python 3’ten bahsederek) geçtiğini söylüyor. – goelakash