2016-08-04 3 views
1

を引用:のPython 3 csv.writer版画 "バイト" と、このコードは、私が期待するものないのPython 2では

import csv 
import sys 

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

それは印刷されます。

hello,world 

しかし、Pythonの3中に、 CSVは、一般的なデータ交換フォーマットであるため

hello,b'world' 

、および他のないシステムになったのは:bytesをプレフィックスと引用符で印刷されていますPythonが何をb''であるか知っているよりも、私はこの動作を無効にする必要があります。しかし、私はどのように考え出していない。

もちろん、すべてbytesにはstr.decodeを使用できますが、それは不便で非効率的です。私が本当に欲しいのは、リテラルバイトをファイルに書き込むか、エンコード(例えば、 'ascii')をcsv.writer()に渡すことです。その結果、表示されるbytesオブジェクトのデコード方法を知ることができます。

答えて

0

Python 3でcsvモジュールを使用して、バイト文字列を明示的にユニコード文字列に変換する必要がないとは考えられません。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

バイト文字列とユニコード文字列は、Python 2でも2種類あります。 Python 2では、デフォルトの 'ascii'コーデックを使用して暗黙的に変換できます。 –

+0

@マーク:ありがとう...答えはそれに応じて更新されました。 – 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()]) 
関連する問題