Pythonでcsvを扱うと改行コードが0D 0D 0Aになる問題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
Hiragi(GKUTH)
記事: 167
登録日時: 8年前
住所: 大阪府
連絡を取る:

Pythonでcsvを扱うと改行コードが0D 0D 0Aになる問題

#1

投稿記事 by Hiragi(GKUTH) » 2年前

いつもお世話になっています。現在Pythonの勉強を進めており、csvを扱うプログラムを書いている時にこの問題に遭いました。

OS:Windows 10 64bit
Python3.5 (WinPython3.5.2.2 64bit)

以下のプログラムは、電話帳のアプリケーションです。
AddressBookクラスはユーザーが連絡先データの登録、表示、検索、ファイルからの読み込み及びファイルへの書き込みが出来ます。
その中でファイルへの書き込みの部分でcsvモジュールを用いてファイルを出力すると改行コードが0D 0D 0Aとなってしまい、環境によっては
改行が二回行われてしまう問題が出ています。通常の0D 0Aで出力させる方法は無いでしょうか?
以下にソースを示します。まだ始めたばかり故、見にくい部分があるかもしれませんがご了承ください。
(codeタグにpythonを指定すると一部の文字が見えなくなる問題が発生したためC++を指定しています。)

コード:

import csv
#dictで順序どおりに登録させるためのモジュール
from collections import OrderedDict

  #電話帳クラス
class AddressBook():
  person_list = []  #登録データのリスト

    #データの登録
  def Register(self,fn,ln,pn,ma,bd_y,bd_m,bd_d):
    tp = (("firstname",fn),("lastname",ln),("phonenum",str(pn)),("mailadd",ma),("Bd_y",bd_y),("Bd_m",bd_m),("Bd_d",bd_d))
    dc = OrderedDict(tp)
    self.person_list.append(dc)
    
    #登録データの表示
  def DispAll(self):
    num = 1
    print("Display user Data.")
    for li in self.person_list:
      print("Data "+str(num))
      print("Name:"+li["firstname"] + li["lastname"])
      print("PhoneNum:"+li["phonenum"])
      print("Mailaddress:"+li["mailadd"])
      print("BIrthday:"+str(li["Bd_y"])+"/"+str(li["Bd_m"])+"/"+str(li["Bd_d"]))
      num = num + 1
      print("")
    print("End Data.")
    
    #登録データのcsv書き出し
  def WriteToCSV(self):
    with open("AddressBook.csv","w") as f:  #書き込みモードでファイルを開く
      writer = csv.writer(f)
      for persondata in self.person_list: #一行づつpersondataに入れて
        writer.writerow(persondata.values())  #書き込む
    
    #登録データの読み込み
  def ReadFromCSV(self):
    with open("AddressBook_.csv","r") as f:
      reader = csv.reader(f)
      for row in reader:
        tp = (("firstname",row[0]),("lastname",row[1]),("phonenum",row[2]),("mailadd",row[3]),("Bd_y",row[4]),("Bd_m",row[5]),("Bd_d",row[6]))
        dc = OrderedDict(tp)
        self.person_list.append(dc)
        print(row)  #確認
    
    #登録データの検索
  def SearchDB(self,word):
    for v in self.person_list:
      if word in v["firstname"] or v["lastname"]:
        print("Hit:" + v["firstname"] + v["lastname"])
        return True
    print("Data Not Found.")
    return False
    
db = AddressBook()

db.Register("hoge","fuga","09000000000","hogefuga@hogehoge.com","2000","1","1")
db.Register("hoge","fu","09000000001","hogefuga@hoge.com","2000","1","1")
db.Register("hoge","ga","09000000002","hofuga@hogehoge.com","2000","1","1")
db.Register("ho","fuga","09000000003","hogefu@hogeho.com","2000","1","1")
db.DispAll()
db.WriteToCSV()
このプログラムによって出力されるファイルは以下の通りです。

コード:

hoge,fuga,09000000000,hogefuga@hogehoge.com,2000,1,1

hoge,fu,09000000001,hogefuga@hoge.com,2000,1,1

hoge,ga,09000000002,hofuga@hogehoge.com,2000,1,1

ho,fuga,09000000003,hogefu@hogeho.com,2000,1,1
ブラウザによっては空行があるように見えますが、例えばWindows標準のメモ帳の場合は空行が無いように見えます。
解決策は無いでしょうか、よろしくお願いします。
だいがくせい!

アバター
みけCAT
記事: 6151
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: Pythonでcsvを扱うと改行コードが0D 0D 0Aになる問題

#2

投稿記事 by みけCAT » 2年前

31行目の"w"を"wb"にして、バイナリモードで書き込むようにするといいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ARCS

Re: Pythonでcsvを扱うと改行コードが0D 0D 0Aになる問題

#3

投稿記事 by ARCS » 2年前

ドキュメントにきちんと記載されていますが…
https://docs.python.jp/3/library/csv.html

openの際にnewline=''を指定して開きます。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 8年前
住所: 大阪府
連絡を取る:

Re: Pythonでcsvを扱うと改行コードが0D 0D 0Aになる問題

#4

投稿記事 by Hiragi(GKUTH) » 2年前

>>みけCAT様
返信ありがとうございます。
そのように変更した結果、書き込む際にbytes-like objectにする必要があるらしく、strとの互換性もあまり良くなかったため、ARCS様の案を採用しました。

>>ARCS様
返信ありがとうございます。
ドキュメントをよく読み込んでいませんでした。申し訳ありません。
ご指摘どおり修正すると、期待通りの動作をしました。ありがとうございました。

変更箇所のみ抜粋

コード:

    #登録データのcsv書き出し
  def WriteToCSV(self):
    with open("AddressBook.csv","w",newline="") as f:  #書き込みモードでファイルを開く
      writer = csv.writer(f)
      for persondata in self.person_list: #一行づつpersondataに入れて
        writer.writerow(persondata.values())  #書き込む
だいがくせい!

返信

“C言語何でも質問掲示板” へ戻る