<p>通过创建自己版本的类/值,您至少可以部分地避开<code>csv</code>模块所做的工作:</p>
<pre><code>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)]
</code></pre>
<p>结果:</p>
<pre class="lang-none prettyprint-override"><code> input: [['None value', None], ['NONE value', NONE], ['empty string', '']]
output: [['None value', ''], ['NONE value', 'NONE'], ['empty string', '']]
</code></pre>
<p>使用<code>NONE</code>而不是<code>None</code>将保留足够的信息,使您能够区分它和任何实际的空字符串数据值。</p>
<p><strong>更好的选择……</strong><br/>
您可以使用相同的方法来实现一对相对轻量级的<code>csv.reader</code>和<code>csv.writer</code>“代理”类-这是必需的,因为您实际上无法对用C编写的内置<code>csv</code>类进行子类化,而不会带来很多开销(因为大多数处理仍然由底层执行内置)。这将使事情变得完全透明,因为它都封装在代理中。</p>
<pre><code>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)]
</code></pre>
<p>结果:</p>
<pre class="lang-none prettyprint-override"><code> input: [['None value', None], ['empty string', '']]
output: [['None value', None], ['empty string', '']]
</code></pre>