Pythonのopenで改行コードが変わった話 in Windows

Pythonでちょっとしたスクリプトを書いていたのですが、どうにも入力ファイルと出力ファイルの改行コードが変わってしまってちょっとはまったので、対応メモです。

環境はWindows 10 + Python3.5になります。

そもそも改行コードの確認方法がわからない人は、こちらを参考にしてください。

現象

このようにファイルを1行ずつ読み込んで出力するだけのプログラムを作ります。

with open("./input.txt") as f:
  for line in f:
    print(line, end='')

input.txtの改行コードは\r\nです。

$ od -c input.txt
0000000   h   o   g   e  \r  \n   f   u   g   a  \r  \n   p   i   y   o
0000020

実行して結果をファイルに出力します。

$ python3 main.py > output.txt

output.txtの改行コードは\nになってしまいます。ついでにファイルの最後にも改行コードが付与されています。

$ od -c output.txt
0000000   h   o   g   e  \n   f   u   g   a  \n   p   i   y   o  \n
0000017

解決策

先ほどのプログラムをこのように修正します。opennewline引数を追加してやりました。

with open("./input.txt", newline='') as f:
  for line in f:
    print(line, end='')

このプログラムで出力されたファイルの改行コードは、変換されずにそのままになります。

$ od -c output.txt
0000000   h   o   g   e  \r  \n   f   u   g   a  \r  \n   p   i   y   o
0000020

newlineを指定しない場合、デフォルトではNoneになります。このときの動作は、\r\n\r\nを改行コードとしてみなして、勝手に全部\nとして扱います。
newline=''とすると、改行コードを変換せずそのまま扱います。

試してはいませんが、newline\r\nとかを指定すれば、\r\nだけを改行コードとして扱えたりもするらしいです。

勝手に改行コード変えられると思わぬところで躓くことがあると思うのですが、なぜデフォルトで変換するような挙動になってるんでしょうね。

参考:

組み込み関数
Python インタプリタには数多くの関数と型が組み込まれており、いつでも利用できます。それらをここにアルファベット順に挙げます。,,,, 組み込み関数,,, A, abs(), aiter(), all(), anext(), any()...

コメント