2013-10-11 5 views
10

के साथ मैं पाइथन में csv.writer के साथ कस्टम quoting को परिभाषित करने का एक तरीका ढूंढ रहा हूं।सीएसवी लेखक कस्टम उद्धरण

csv.QUOTE_ALL, csv.QUOTE_MINIMAL, csv.QUOTE_NONNUMERIC, csv.QUOTE_NONE 

हालांकि मैं एक के हवाले से व्यवस्था है जिसके अनुकरण करेगा Postgres 'FORCE QUOTE * की जरूरत है, अर्थात सभी गैर-कोई नहीं मान बोली होगा: वहाँ मूल्यों qoute करने के लिए 4 में निर्मित तरीके हैं। csv.QUOTE_ALL के साथ पायथन कोई भी '' में नहीं बदलेगा लेकिन मैं इसके बजाय खाली स्ट्रिंग रखना चाहता हूं।

क्या यह csv मॉड्यूल के साथ ऐसा करना संभव है (मुझे हैक्स में दिलचस्पी नहीं है, मैं पहले से ही ऐसा कर रहा हूं: पी)? या क्या मुझे कुछ कस्टम सीएसवी पार्सर लिखने/प्राप्त करने के लिए मजबूर किया गया है?

और आम तौर पर: csv मॉड्यूल के लिए कस्टम उद्धरण तंत्र लिखना संभव है?

उत्तर

9

अक्षम csv के हवाले से और उद्धरण अपने आप को जोड़:

def quote(col): 
    if col is None: 
     return '' 
    # uses double-quoting style to escape existing quotes 
    return '"{}"'.format(str(col).replace('"', '""')) 

writer = csv.writer(fileobj, quoting=csv.QUOTE_NONE, escapechar='', quotechar='') 

for row in rows: 
    writer.writerow(map(quote, row)) 

दोनों escapechar और quotechar की स्थापना तार खाली करने के लिए आप मॉड्यूल अपने पहले से ही उद्धृत मूल्यों के हवाले से बचने के द्वारा।

उपर्युक्त कार्य तब तक काम करते हैं जब तक आप डिलीमीटर का उपयोग csv मानों में नहीं करते हैं।

ध्यान दें कि इस समय तक यह सिर्फ आसान हो अल्प विराम द्वारा सीमांकित लाइनों लिखने के लिए होगा अपने आप को:

with open(filename, 'w'), fd: 
    for row in rows: 
     fd.write(','.join(map(quote, row)) + '\r\n') 
+1

पहले ही कोशिश की गई है: समस्या यह है कि आपको 'QUOTE_NONE' के साथ 'escapechar' निर्दिष्ट करना होगा और फिर यह उद्धरण से बच निकलेगा। – freakish

+0

@ फ़्रीकिश: केवल तभी 'उद्धरण' सेट किया गया है। –

+0

यह डिफ़ॉल्ट रूप से '' 'है, है ना? – freakish

4

मैं अपने खुद के सीएसवी लेखक जो वास्तव में करता है लिखा है कि मैं क्या चाहता हूँ:

class PostgresCSVWriter(object): 
    def __init__(self, stream, quotechar="\"", delimiter=",", escapechar="\\"): 
     self.stream = stream 
     self.quotechar = quotechar 
     self.delimiter = delimiter 
     self.escapechar = escapechar 
     self.buffer_size = 16384 

    def _convert_value(self, obj): 
     if obj is None: 
      return "" 
     value = str(obj) 
     value = value.replace(self.quotechar, self.quotechar+self.quotechar) 
     value = value.replace(self.delimiter, self.escapechar+self.delimiter) 
     return self.quotechar+value+self.quotechar 

    def _convert_row(self, row): 
     return self.delimiter.join(self._convert_value(v) for v in row) + "\r\n" 

    def writerow(self, row): 
     self.stream.write(self._convert_row(row)) 

    def writerows(self, rows): 
     data = "" 
     counter = 0 
     for row in rows: 
      buf = self._convert_row(row) 
      data += buf 
      counter += len(buf) 
      if counter >= self.buffer_size: 
       self.stream.write(data) 
       data = "" 
       counter = 0 

     if data: 
      self.stream.write(data) 

अगर किसी को इसके साथ कोई समस्या दिखाई देती है, तो कृपया मुझे बताएं। मैं अभी भी csv मॉड्यूल के साथ समाधान ढूंढ रहा हूं।

संबंधित मुद्दे