2016-08-04 25 views
1

在Python 2這個代碼就我所期望的:的Python 3 csv.writer打印 「字節」 前綴並引用

import csv 
import sys 

writer = csv.writer(sys.stdout) 
writer.writerow([u'hello', b'world']) 

它打印:

hello,world 

但是在Python 3, bytes都印有一個前綴和引用:

hello,b'world' 

由於CSV是一個通用的數據交換格式,並且由於沒有其他系統比Python知道什麼b''是,我需要禁用此行爲。但我還沒有想出如何。

當然,我可以首先在所有的bytes上使用str.decode,但這很不方便且效率低下。我真正想要的是將文字字節寫入文件,或將編碼(例如'ascii')傳遞到csv.writer(),以便它知道如何解碼它看到的任何對象。

回答

0

我不認爲有什麼辦法可以避免在Python 3中使用csv模塊將字節字符串明確地轉換爲unicode字符串。在Python 2中,它們被隱式轉換爲ASCII。

爲了使這更容易,您可以有效地將csv.writer(或包裝)對象子類化,如下所示,這將使過程更加方便。

import csv 

class MyCsvWriter(object): 
    def __init__(self, *args, **kwrds): 
     self.csv_writer = csv.writer(*args, **kwrds) 

    def __getattr__(self, name): 
     return getattr(self.csv_writer, name) 

    def writerow(self, row): 
     self.csv_writer.writerow(
      str(v, encoding='utf-8') if isinstance(v, bytes) else v for v in row) 

    def writerows(self, rows): 
     for row in rows: 
      self.writerow(row) 

with open('bytes_test.csv', 'w', newline='') as file: 
    writer = MyCsvWriter(file) 
    writer.writerow([u'hello', b'world']) 
+0

字節字符串和unicode字符串在Python 2中也是兩種不同的類型。 Python 2只允許使用默認的'ascii'編解碼器進行隱式轉換。 –

+0

@Mark:謝謝......答案相應更新。 – martineau

0

csv寫入文本文件,並預計在Python的Unicode(文本)字符串3.

csv寫入二進制文件,並預計在Python 2字節字符串,但允許字節串Unicode字符串的隱式編碼使用編解碼器的默認ascii。 Python 3不允許隱式轉換,因此您不能真正避免它:

#!python3 
import csv 
import sys 
writer = csv.writer(sys.stdout) 
writer.writerow(['hello', b'world'.decode()])