2015-04-24 17 views
11

DÜZENLEME: Başlığa koydum, ancak vücutta bahsetmediğimi fark ettim. Bu, Windows'a özgü gibi görünüyor.Python'da bir .CSV dosyası yazmak, hem Python 2.7+ hem de Python 3.3+ Windows'ta çalışır.

Her iki Python 2.7 ve 3.3 ile çalışan bir komut dosyasında csv Python modülünü kullanarak çıktı yazmakta zorlanıyorum.

Python 2.7 beklendiği gibi çalışır

Önce şunu deneyin:

TypeError: 'str' does not support the buffer interface 

yüzden 'wb''wt' değişir

: aynı şeyi Python 3.3 çalıştırıldığında

with open('test.csv', 'wb') as csv_file: 
    writer = csv.DictWriter(csv_file, ['header1', 'header2']) 
    writer.writeheader() 
    for item in items: 
     writer.writerow(item) 

Ancak, birlikte rüzgar ve çalışır, ancak şimdi dosyadaki her satırda fazladan boş bir satır var.

with open('test.csv', 'wt') as csv_file: 

için:

düzeltmek için, ben değiştirmek

with open('test.csv', 'wt', newline='') as csv_file: 

Ama şimdi, Python 2.7 kırar:

TypeError: 'newline' is an invalid keyword argument for this function 

ben sadece böyle bir şey yapabileceğini biliyorum :

try: 
    with open('test.csv', 'wt', newline='') as csv_file: 
     writer = csv.DictWriter(csv_file, ['header1', 'header2']) 
     writer.writeheader() 
     for item in items: 
      writer.writerow(item) 
except TypeError: 
    with open('test.csv', 'wb') as csv_file: 
     writer = csv.DictWriter(csv_file, ['header1', 'header2']) 
     writer.writeheader() 
     for item in items: 
      writer.writerow(item) 

Bununla birlikte, bu ciddi olarak çok küçük bir kopyalamaya sahip.

Bunu daha temiz bir şekilde yapan var mı?

DÜZENLEME: Test verileri basittir ve hiçbir yeni satır ya da bir şey vardır:

items = [{'header1': 'value', 'header2': 'value2'}, 
     {'header1': 'blah1', 'header2': 'blah2'}] 
+0

Sadece "wb" veya "wt" yerine "w'" kullanamaz mısınız? – nathancahill

+0

Python 2'de betiği çalıştırırken dizeler 'item' listesindeki' unicode' dizgileri mi? Değerler her zaman ASCII midir, yoksa kodlanması gereken fazladan karakterler içerebilirler mi? Aynı kodu Python'un her iki sürümünde de çalıştırabilseniz bile, aynı sonuçları almayabilirsiniz! – Blckknght

+0

@Blckknght - Test verilerini sorunun altına ekledim. Bu sadece ASCII metindir. – Tamerz

cevap

6

Ben birkaç yolu denedim.

with open('test.csv', 'w') as csv_file: 
    writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n') 
    # write something 
+1

Bunu yaparsam, yine de her satırda boş satırlar alırım. Bunu Windows veya başka bir şeyde denediniz mi? – Tamerz

+0

@Tamerz Verilerinizde fazladan yeni satırlar bulunduğundan fazladan satırlar alacaksınız. '.strip()' ihtiyacınız olan şey olabilir. – gboffi

+0

@Tamerz Sahte verilerle denedim ve iyi çıktı. Ben de senin verilerinde yanlış bir şey olduğunu düşünüyorum. – skyline75489

7

İşte basit bir jenerik yolu: Bildiğim kadarıyla gördüğünüz gibi, 'w' kullanarak çözüm basit olabilir

import sys 

if sys.version_info[0] == 2: # Not named on 2.6 
    access = 'wb' 
    kwargs = {} 
else: 
    access = 'wt' 
    kwargs = {'newline':''} 

with open('test.csv', access, **kwargs) as csv_file: 
    writer = csv.DictWriter(csv_file, ['header1', 'header2']) 
    writer.writeheader() 
    for item in items: 
     writer.writerow(item) 

burada prensibi Python 2 ile arasındaki farkları mücadele etmeye değil 3 ama şartlı kod var. Bu tür bir test olmaksızın sadece kod yazarken bu kadar ileri gidebilir, er ya da geç Python versiyonunu test etmeniz gerekecektir.

+0

Belki de “kwargs” ın dahil edilmesinin iyi bir çözüm olabileceğini düşündüm. Hala güzel değil ama sahip olduğum tüm çoğaltmalardan anlamlı derecede daha iyi. Bu kesinlikle benim senaryoda çalışacaktır. Teşekkür ederim. – Tamerz

+0

@ skyline75489'un verdiği yanıtla gittim ama hala gelecekte kullanmak için bunu seviyorum. Tam olarak bunu yapmaya ihtiyacım vardı ama en iyi yolu bilmiyordum. – Tamerz

+0

@Tamerz: Benzer bir soruya [yanıtım] (http://stackoverflow.com/a/41913382/355230) bakın. Python'un her iki sürümünde de çalışır ve hem okuma hem de yazma için dosyaları açar (artı açık() 'gibi, açık olarak belirtilmemişse okuma modunun varsayılanı). Ayrıca küresel değişkenlerin kullanımını gerektirmez. – martineau

İlgili konular