csv
シングルトンのNone
ようなクラス/値の独自のバージョンを作成することにより、モジュールが行うことを少なくとも部分的に回避できます。
from __future__ import print_function
import csv
class NONE(object):
''' None-like class. '''
def __repr__(self): # Method csv.writer class uses to write values.
return 'NONE' # Unique string value to represent None.
def __len__(self): # Method called to determine length and truthiness.
return 0
NONE = NONE() # Singleton instance of the class.
if __name__ == '__main__':
try:
from cStringIO import StringIO # Python 2.
except ModuleNotFoundError:
from io import StringIO # Python 3.
data = [['None value', None], ['NONE value', NONE], ['empty string', '']]
f = StringIO()
csv.writer(f).writerows(data)
f = StringIO(f.getvalue())
print(" input:", data)
print("output:", [e for e in csv.reader(f)])
結果:
input: [['None value', None], ['NONE value', NONE], ['empty string', '']]
output: [['None value', ''], ['NONE value', 'NONE'], ['empty string', '']]
NONE
の代わりに使用None
すると、それと実際の空の文字列データ値を区別できるように十分な情報が保持されます。
さらに良い代替…</h3>
同じアプローチを使用して、比較的軽量csv.reader
でcsv.writer
「プロキシ」なクラスのペアを実装できます。これは、C で記述された組み込みクラスを実際にサブクラス化できないため必要ですcsv
。多くのオーバーヘッドを導入する必要はありません (処理は、基になるビルトインによって引き続き実行されます)。これにより、すべてがプロキシ内にカプセル化されるため、進行中のことが完全に透過的になります。
from __future__ import print_function
import csv
class csvProxyBase(object): _NONE = '<None>' # Unique value representing None.
class csvWriter(csvProxyBase):
def __init__(self, csvfile, *args, **kwrags):
self.writer = csv.writer(csvfile, *args, **kwrags)
def writerow(self, row):
self.writer.writerow([self._NONE if val is None else val for val in row])
def writerows(self, rows):
list(map(self.writerow, rows))
class csvReader(csvProxyBase):
def __init__(self, csvfile, *args, **kwrags):
self.reader = csv.reader(csvfile, *args, **kwrags)
def __iter__(self):
return self
def __next__(self):
return [None if val == self._NONE else val for val in next(self.reader)]
next = __next__ # Python2.x compatibility.
if __name__ == '__main__':
try:
from cStringIO import StringIO # Python 2.
except ModuleNotFoundError:
from io import StringIO # Python 3.
data = [['None value', None], ['empty string', '']]
f = StringIO()
csvWriter(f).writerows(data)
f = StringIO(f.getvalue())
print("input : ", data)
print("ouput : ", [e for e in csvReader(f)])
結果:
input: [['None value', None], ['empty string', '']]
output: [['None value', None], ['empty string', '']]