[前回] Python I/Oの再考(1): ストリームの種類と比較検証
はじめに
前回は、Python I/Oの基本をおさらいしました。
今回は、io
モジュールの高レベルインターフェースです。
io
モジュールが提供する高レベルインターフェース
バッファと文字コードに関係するインターフェースを取り上げます。
そもそもI/Oになぜバッファ(メモリ領域)が必要か
- Rawストリーム(バッファリングなし)
- ストリームの読み書きで、1バイトずつ処理するため性能が落ちる
- バイナリストリーム(バッファリングあり)
- バッファにデータをためて、一度に処理
io.DEFAULT_BUFFER_SIZE
インターフェース
※ 参照: https://docs.python.org/ja/3/library/io.html#io.DEFAULT_BUFFER_SIZE
-
バッファリング付きI/Oクラスで利用されるバッファの、デフォルトサイズを表す
-
open()
時のバッファサイズには、ファイルのblksize
値が使用される(os.stat()で取得可)- AlmaLinuxで取得した結果、
4KB
- AlmaLinuxで取得した結果、
>>> import os
>>> os.stat("ファイル名").st_blksize
4096
テキストストリームの操作で、文字コード(encoding)指定を忘れず
-
テキストストリームのデフォルト文字コード
- OSのロケールに依存
- Windowsで取得してみると、
cp932
>>> import locale >>> locale.getpreferredencoding(False) 'cp932'
- AlmaLinuxで取得してみると、
UTF-8
>>> import locale >>> locale.getpreferredencoding(False) 'UTF-8'
- Windowsで取得してみると、
- OSのロケールに依存
-
テキストファイルを開くときは、文字コードを明示的に指定する必要あり
- 理由は、Windowsはロケールの文字コードがUTF-8でないため
- UTF-8でエンコードされたテキストファイルが文字化けする
- 文字コードの指定方法
- UTF-8を使用する場合、
encoding="utf-8"
を渡す
- UTF-8を使用する場合、
- 理由は、Windowsはロケールの文字コードがUTF-8でないため
-
Python 3.10以降で、現在ロケールの文字コードを使用する方法
-
encoding="locale"
を渡す
-
io.text_encoding(encoding, stacklevel=2, /)
※ 参照: https://docs.python.org/ja/3/library/io.html#io.text_encoding
-
Python 3.10以降で使用可能な、文字コード指定をチェックしてくれるヘルパー関数
-
open()
またはTextIOWrapper
で、encoding=None
パラメーターを指定する場面で使用
-
-
関数の戻り値
-
encoding
がNone
でない場合-
encoding
を返す
-
-
encoding
がNone
の場合-
locale
を返す
-
-
-
デフォルト文字コードが使用される場合、
EncodingWarning
を発行するように設定可能-
EncodingWarning
の発行条件-
sys.flags.warn_default_encoding
がtrue
で、encoding
がNone
の場合
-
-
stacklevel
は、警告が発行される場所を指定- 下記例では、
read_text()
の呼び出し元に対し、EncodingWarning
が発行される
- 下記例では、
-
def read_text(path, encoding=None):
encoding = io.text_encoding(encoding) # stacklevel=2
with open(path, encoding) as f:
return f.read()
おわりに
io
モジュールの高レベルインターフェースを理解しました。
次回をお楽しみに。