你至少可以部分地侧步什么csv
模块会创建自己的单身None
般类/值的版本:
class NONE(object):
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 # (optional)
NONE = NONE() # singleton instance of the class
import csv
import cStringIO
data = [['None value', None], ['NONE value', NONE], ['empty string', '']]
f = cStringIO.StringIO()
csv.writer(f).writerows(data)
f = cStringIO.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
将保留足够的信息,以便您能够区分它和任何实际的空字符串数据值。
甚至更好的选择...
您可以用同样的方法来实现对相对轻便csv.reader
和csv.writer
“代理”类—必要的,因为你不能真正继承内置csv
类其中都是在C —中编写的,没有引入大量开销(因为大部分的处理仍然由底层的内置插件执行)。这将使得完全透明,因为它全部封装在代理内。
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):
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 self.reader.next()]
if __name__ == '__main__':
import cStringIO as StringIO
data = [['None value', None], ['empty string', '']]
f = StringIO.StringIO()
csvWriter(f).writerows(data)
f = StringIO.StringIO(f.getvalue())
print " input:", data
print "output:", [e for e in csvReader(f)]
结果:
input: [['None value', None], ['empty string', '']]
output: [['None value', None], ['empty string', '']]
Yep证实:在Modules/_csv.c中查看csv_writerow(if(field == Py_None)...)。没有办法区分''和None。真是一个耻辱,鉴于方言抽象,你会希望有更多的灵活性。你提到csv模块的其他限制,你介意阐述(如果还有其他问题,我真的应该开始看其他csv阅读写作)? – user1509316 2012-07-08 00:48:19
我发现一个有限的问题是分隔符必须是单个字符。所以你不能解析一个文件,其中列被两个标签分隔。就像你遇到的None事情一样,这很容易解决,但仍然很烦人。 – BrenBarn 2012-07-08 02:21:02
另一个是模块内的硬编码ascii限制。 – 2013-01-18 14:02:11