LoginSignup
2
0

More than 1 year has passed since last update.

Python I/Oの再考(2): ioモジュールの高レベルインターフェース

Last updated at Posted at 2022-08-20
[前回] Python I/Oの再考(1): ストリームの種類と比較検証

はじめに

前回は、Python I/Oの基本をおさらいしました。
今回は、ioモジュールの高レベルインターフェースです。

ioモジュールが提供する高レベルインターフェース

バッファと文字コードに関係するインターフェースを取り上げます。

そもそもI/Oになぜバッファ(メモリ領域)が必要か

  • Rawストリーム(バッファリングなし)
    • ストリームの読み書きで、1バイトずつ処理するため性能が落ちる

image.png

  • バイナリストリーム(バッファリングあり)
    • バッファにデータをためて、一度に処理

image.png

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
>>> 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はロケールの文字コードがUTF-8でないため
      • UTF-8でエンコードされたテキストファイルが文字化けする
    • 文字コードの指定方法
      • UTF-8を使用する場合、encoding="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パラメーターを指定する場面で使用
  • 関数の戻り値

    • encodingNoneでない場合
      • encodingを返す
    • encodingNoneの場合
      • localeを返す
  • デフォルト文字コードが使用される場合、EncodingWarningを発行するように設定可能

    • EncodingWarningの発行条件
      • sys.flags.warn_default_encodingtrueで、encodingNoneの場合
    • 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モジュールの高レベルインターフェースを理解しました。
次回をお楽しみに。

[次回] Python I/Oの再考(3): I/Oストリームのクラス階層
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0