質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyCharm

エディター・開発ツール

Q&A

解決済

3回答

4862閲覧

Windows版PyCharmでログファイルの改行コードを制御したい

mendel

総合スコア27

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

PyCharm

エディター・開発ツール

0グッド

0クリップ

投稿2018/03/04 00:20

環境
Windows10 Home
Python3.6.4
PyCharm community 2017.3
Build #PC-173.3942.36 build on December 14.2017

Python

1file_h = logging.FileHandler('test.log') 2logger.addHandler(file_h)

上記のコードで作成される「test.log」の改行コードが[CR+LF]になっています。
これを常にLFのみにしたい。

確認したこと。

[File]>[Setting]>[Code Style]にて
[Line separator]は[Unix and OS X(\n)]に設定済み。

ログファイルはソースコードではないので、改行コードは気にしなくてもよいのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

結論:FileHandlerを使用する限りでは、質問文の要件は満たせないです。

理由:FileHandlerの親クラスであるStreamHandlerに終端記号を表すterminator属性があります。
terminator属性の値を変更すると終端記号を変更できますが、
windows環境においてはログファイルをテキストモードで書き込む時に\n (LF)は\r\n (CR)(LF)に自動変換されます

自動変換が行われないように、FileHandlerをバイナリモード(コンストラクタの引数:modeを設定)で書き込めば良いように思いますが。
FileHandlerの親クラスでログ・ファイルに書き込む時に内部でmsg = self.format(record)strに型変換を行っているためバイナリデータを書き込めません。


後から見た人用纏め。
で、ログファイルをLFで出力するには結局どうしたらいいのか?
FileHandlerの代わりにKSwordOfHasteさんのコメントにある、KSwordOfHasteさんが作成したNLFileHandlerを使えば可能です。

投稿2018/03/04 01:25

編集2018/03/04 10:11
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mendel

2018/03/04 05:29

回答ありがとうございます。 本来ならこちらをベストアンサーとすべきでした。 操作に慣れておらず別の回答をベストアンサーとしてしまい 申し訳ありません。 > FileHandlerを使用する限りでは 各種ハンドラを使えるように勉強しろと言うことですね。 リンクを貼っていいただいたチュートリアルとソースコードを見ました。 疑問が解消しました。 ありがとうございました。
umyu

2018/03/04 08:25

ベストアンサーはきにせずにー。質問が解決してよかったです。。
KSwordOfHaste

2018/03/04 11:11

質問者さん!ベストアンサーは付け替えられます!やってみてくださいな。
guest

0

後からhandler.streamをすげ替えてもOK。

python

1from io import TextIOWrapper 2from logging import FileHandler 3from logging import getLogger 4 5handler = FileHandler("test.log") 6handler.stream = TextIOWrapper(handler.stream.detach(), 7 encoding=handler.stream.encoding, 8 newline="\n") 9 10logger = getLogger("test") 11logger.addHandler(handler) 12logger.error("test")

投稿2018/03/04 11:58

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ログファイルはソースコードではないので、改行コードは気にしなくてもよいのでしょうか?

気にしなくてよいというより「実行したOSで一番自然な改行コードにする」のをよしとしてPythonのライブラリーは動いているという認識ができているかどうかです。

Windowsでメモ帳やその他のCR+LFを改行としてみなすエディターで普通に閲覧できることを期待するならCR+LFとして動作させるのが妥当でしょう。

一方ログファイルを「そのままバイナリー転送してLinuxへ送りたい」なんてことを考えるならCRは付けたくないということがあるかも知れません。

どんな場合でも闇雲にCRを取るのが妥当とか取らないことが妥当とは言い切れません。ログファイルをどういうふうに扱いたいかによると思います。

個人的な意見としては「Windowsで実行するならCR+LFを付けといた方がなにかと便利」です。それを他の環境へ転送するなら「テキストを料理するなんらかのツールで」CRを削除すればいいと思います。


追記:
PyCharm (Windows 10, Python3.6)で動きをみたところumyuさんがコメントしておられるように「ライブラリーのかなり深いところで改行コードの置き換えが行われているらしい」ことが観察できました。

適当なエンコーダーで文字列=>バイト列へ変換することも含めてテキストストリームを自前実装することもできるとは思いますが、上記コメントに書いたようにそこまで手間をかけてCRを取る必要もない気がしました。

投稿2018/03/04 03:46

編集2018/03/04 04:04
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mendel

2018/03/04 05:25

> 実行したOSで一番自然な改行コードにする わかりませした。貴重な示唆をありがとうございます。 手を加えずに書き出すに任せます。 ただ、バイナリデータを扱う方法の勉強を兼ねて、 改行コードとBOMありなし判定・変換のスクリプトを書いてみます。
KSwordOfHaste

2018/03/04 05:28

自分も本サイトで知ったのですがPythonにはBOMありutf8を自動認識してくれるエンコーダー/デコーダーがあるようですので自前で実装するよりそれを使った方がエレガントかも知れません。
KSwordOfHaste

2018/03/04 09:38 編集

> open関数の引数 あ・・・なるほどです。もしやるなら自分が書いたようなどろくさい方法ではなく class NLFileHandler(logging.FileHandler):  def _open(self):   return open(self.baseFilename, self.mode, encoding=self.encoding, newline='\n') file_h = NLFileHandler('test.log') ... とでもした方が簡単ですね? ---追記--- いやそもそもopenを直接使ってしまえばいいんでしょうか? あまり調べずにコメントしてしまいすみません。><
umyu

2018/03/04 09:58 編集

return open(self.baseFilename, self.mode, encoding=self.encoding, newline=self.terminator) こうでしょうか、python本家にバグ報告方法みてたら結構手間な気がしてきました。 https://devguide.python.org/pullrequest/ openもそうですけど、_付きのprivateメソッドをオーバーライドしてるのもadhookな感じです。 でも質問者様の要求は満たせるかと。
KSwordOfHaste

2018/03/04 10:21

self.terminatorの機能的な意味とopenの引数に指定する改行コードの意味が同一と見做してよいかどうか自分にはわかりませんでした。 self.terminatorはOSの違いによらず同一の文字'\n'がデフォルトだと思います。それをファイルへ出力する際にCR+LFにするかLFにするかは別の機能のような気がしました。うーん・・・難しいです。
umyu

2018/03/04 10:31 編集

ココらへんです。 https://docs.python.jp/3/library/functions.html#open ストリームへの出力の書き込み時、newline が None の場合、全ての '\n' 文字はシステムのデフォルトの行セパレータ os.linesep に変換されます。 newline が '' または '\n' の場合は変換されません。newline がその他の正当な値の場合、全ての '\n' 文字は与えられた文字列に変換されます。 >self.terminatorの機能的な意味とopenの引数に指定する改行コードの意味が同一と見做してよいかどう macを考慮するなら、CRも考慮しないといけないので複雑になってしまいますので、windowsでLFを出力したいという要件だけ解決するコードですね。 ■現状 mac/linux/windows → StreamHandler#terminatorが'\n'で定義 ファイルopen時にnewlineがNoneのため、書き込んだ'\n'がos.linesepによって自動変換される。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問