10章学習記録 » 履歴 » バージョン 2
Tatsuya ISHIGAKI, 2025/08/29 07:04
| 1 | 1 | Tatsuya ISHIGAKI | # 第10章 汎用 OS・ランタイムサービス |
|---|---|---|---|
| 2 | |||
| 3 | ## 10.1 OS の機能を利用する os |
||
| 4 | |||
| 5 | - 実行中のプロセス属性の操作 |
||
| 6 | |||
| 7 | |プロセス属性|関数| |
||
| 8 | |---|---| |
||
| 9 | |環境変数|`environ()`, `getenv()`, `setenv()`, ...| |
||
| 10 | |ユーザーID|`getuid()`, `setuid()`, `geteuid()`, `seteuid()`, ...| |
||
| 11 | |グループID|`getgid()`, `setgid()`, `getgroups()`, `setgroups()`, ...| |
||
| 12 | |プロセスID|`getpid()`, `getpgid()`, `getppid()`, ...| |
||
| 13 | |スケジューリング優先度|`getpriority()`, `setpriority()`, ...| |
||
| 14 | |||
| 15 | - ファイルとディレクトリの操作 |
||
| 16 | - `pathlib` モジュールの方がおすすめ |
||
| 17 | |||
| 18 | |関数|解説|戻り値|pathlib の同等関数| |
||
| 19 | |---|---|---|---| |
||
| 20 | |`chdir(path)`|作業ディレクトリ設定|None|| |
||
| 21 | |`chmod(path, mod, *, dirfd=None, follow_symlinks=True)`|モード変更|None|`Path.chmod()`| |
||
| 22 | |`chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)`|所有者、グループの変更|None|| |
||
| 23 | |`getcwd()`|現在のディレクトリを取得|str|`Path.cwd()`| |
||
| 24 | |`listdir(path='.')`|ディレクトリ内のファイル、ディレクトリをリスト出力|list|`Path.iterdir()`| |
||
| 25 | |`makedir(path, mode=0o777, *, dir_fd=None)`|ディレクトリ作成|None|`Path.mkdir()`| |
||
| 26 | |`makedirs(name, mode=0o777, exist_od=False)`|中間ディレクトリを含めてディレクトリ作成|None|`Path.mkdir()`| |
||
| 27 | |`remove(path, *, dir_fd=None)`|ファイルを削除 (ディレクトリの場合は OSError)|None|`Path.unlink()`| |
||
| 28 | |`removedirs(name)`|再帰的ディレクトリ削除|None|| |
||
| 29 | |`rename(src dst, *, src_dir_fd=None, dst_dir_fd=None)`|名前変更|None|`Path.rename()`| |
||
| 30 | |`renames(old, new)`|中間ディレクトリ削除・作成を含めた名前変更|None|| |
||
| 31 | |`rmdir(path, *, dir_fd=None)`|ディレクトリを削除|None|`Path.rmdir()`| |
||
| 32 | |`symlink(src, dst, target_is_directory=False, *, dir_fd=None)`|src を指すシンボリックリンクを dst のファイル名で作成|None|`Path.symlink_to()`| |
||
| 33 | |||
| 34 | - ファイルパス関連定数 |
||
| 35 | |定数名|解説|戻り値| |
||
| 36 | |---|---|---| |
||
| 37 | |`curdir`|現在のディレクトリ|str| |
||
| 38 | |`pardir`|親ディレクトリ|str| |
||
| 39 | |`sep`|パス名の区切り文字列|str| |
||
| 40 | |`extsep`|ファイル名と拡張子を分ける文字|str| |
||
| 41 | |`linesep`|行の終端文字列|str| |
||
| 42 | |||
| 43 | - さまざまなシステム情報へのアクセス |
||
| 44 | |||
| 45 | |関数名、辞書名|解説|戻り値| |
||
| 46 | |---|---|---| |
||
| 47 | |`confstr(name)`|システム設定値の文字列取得|str| |
||
| 48 | |`confstr_names`|confstr() に渡すことのできる値を定義した辞書|dict| |
||
| 49 | |`sysconf(name)`|システム設定値の整数取得|int| |
||
| 50 | |`sysconf_names()`|sysconf() に渡すことのできる値を定義した辞書|dict| |
||
| 51 | |`cpu_count()`|CPU数の取得<br>取得できなくても None 返すだけ|int| |
||
| 52 | |`getloadavg()`|過去1分間、5分間、15分間の load average をタプルで返す|(float, float, float)| |
||
| 53 | |||
| 54 | - `os.cpu_count()` に似た動作の関数に `multiprocessing.cpu_count()` がある |
||
| 55 | - 違いは、CPU数を取得できなかった (Python が解決できなかった) 場合の挙動 |
||
| 56 | - `os.cpu_count()` None を返す |
||
| 57 | - `multiprocessing.cpu_count()` 例外 NotImplementedError を送出 |
||
| 58 | |||
| 59 | - ランダムな文字列の生成 |
||
| 60 | - `os.urandom()` **OS が提供する乱数生成機能を用いて** 生成したランダムな bytes オブジェクトを返す |
||
| 61 | - `random` モジュールの疑似乱数より、セキュリティ面では `os` または `secrets` モジュールの乱数生成が推奨されている |
||
| 62 | |||
| 63 | - システム情報取得に使われるサードパーティ製パッケージ psutil |
||
| 64 | - `psutil.cpu_times()` CPU時間を求める |
||
| 65 | - `psutil.virtual_memory()` メモリ使用率に関する統計情報を求める |
||
| 66 | - `psutil.disk_partitions()` マウント済みのディスクパーティション情報を取得 |
||
| 67 | - `psutil.net_ioi_counters()` ネットワーク I/O に関する統計情報を求める |
||
| 68 | |||
| 69 | ## 10.2 ストリームを扱う io |
||
| 70 | open() で開いたファイル同様に扱う、ストリームオブジェクト、file-like オブジェクトについて |
||
| 71 | |||
| 72 | - インメモリなテキストストリームを扱う StringIO |
||
| 73 | - オブジェクト作成 `StringIO(initial_value='', newline='\n')` |
||
| 74 | - `initial_value` 初期値となる文字列 |
||
| 75 | - `newline` 改行文字 |
||
| 76 | |||
| 77 | - `StringIO` クラスのメソッド |
||
| 78 | |メソッド名|解説|戻り値| |
||
| 79 | |---|---|---| |
||
| 80 | |`read(size=-1)`|ストリームの現在オフセットから指定サイズの文字列を返す<br>size が負の値または None なら EOF まで|str| |
||
| 81 | |`write(s)`|ストリームに文字列を書き込む|int| |
||
| 82 | |`tell()`|現在のオフセットを返す|int| |
||
| 83 | |`seek(offset, whence=SEEK_OUT)`|オフセットを指定位置に移動する (詳細省略)|int| |
||
| 84 | |`getvalue()`|ストリームが保持しているすべての内容を文字列で返す (オフセット位置に依らない、オフセットの移動もなし)|str| |
||
| 85 | |`close()`|ストリームを閉じる|None| |
||
| 86 | |||
| 87 | ```python |
||
| 88 | >>> import io |
||
| 89 | >>> stream = io.StringIO("this is test\n") # 初期値を渡すことができる |
||
| 90 | >>> stream.read(10) # ストリームから指定サイズだけ読み出す |
||
| 91 | 'this is te' |
||
| 92 | >>> stream.tell() # 現在のオフセットを返す |
||
| 93 | 10 |
||
| 94 | >>> stream.seek(0, io.SEEK_END) # オフセットをストリームの末尾に変更する |
||
| 95 | 13 |
||
| 96 | >>> stream.write('test') # ストリームに文字列を書き込む |
||
| 97 | 4 |
||
| 98 | >>> print(stream.getvalue()) # ストリームが保持するすべての内容を返す |
||
| 99 | this is test |
||
| 100 | test |
||
| 101 | >>> stream.close() # ストリームを閉じる |
||
| 102 | >>> stream.write('test') # 閉じたあとに書き込もうとすると例外を送出する |
||
| 103 | Traceback (most recent call last): |
||
| 104 | File "<stdin>", line 1, in <module> |
||
| 105 | ValueError: I/O operation on closed file |
||
| 106 | >>> with io.StringIO() as stream: # withブロックを使うことで暗黙的にclose()を呼ぶこともできる |
||
| 107 | ... stream.write('test') |
||
| 108 | ... |
||
| 109 | 4 |
||
| 110 | >>> the_zen_of_python = """The Zen of Python, by Tim Peters |
||
| 111 | ... Beautiful is better than ugly. |
||
| 112 | ... Explicit is better than implicit. |
||
| 113 | ... Simple is better than complex. |
||
| 114 | ... Complex is better than complicated. |
||
| 115 | ... """ |
||
| 116 | >>> stream = io.StringIO(the_zen_of_python) |
||
| 117 | >>> for line in stream: # for文で1行ずつ読み込むこともできる |
||
| 118 | ... line |
||
| 119 | ... |
||
| 120 | 'The Zen of Python, by Tim Peters\n' |
||
| 121 | 'Beautiful is better than ugly.\n' |
||
| 122 | 'Explicit is better than implicit.\n' |
||
| 123 | 'Simple is better than complex.\n' |
||
| 124 | 'Complex is better than complicated.\n' |
||
| 125 | ``` |
||
| 126 | |||
| 127 | - インメモリなバイナリストリームを扱う BytesIO |
||
| 128 | - オブジェクト作成 `BytesIO([initial_value])` |
||
| 129 | - `initial_value` 初期値の bytes オブジェクト |
||
| 130 | |||
| 131 | |メソッド名|解説|戻り値| |
||
| 132 | |---|---|---| |
||
| 133 | |`read(size=-1)`|ストリームの現在オフセットから指定サイズのバイト列を返す<br>size が負の値または None なら EOF まで|bytes| |
||
| 134 | |`write(s)`|ストリームにバイト列を書き込む|int| |
||
| 135 | |`tell()`|現在のオフセットを返す|int| |
||
| 136 | |`seek(offset, whence=SEEK_OUT)`|オフセットを指定位置に移動する (詳細省略)|int| |
||
| 137 | |`getbuffer()`|バッファーの内容を返す<br>この値は読み込みおよび書き込みが可能なビューで、値を更新するとバッファーの内容も更新される|memoryview| |
||
| 138 | |`getvalue()`|バッファーの内容を返す<br>この値を更新ができない|bytes| |
||
| 139 | |`close()`|ストリームを閉じる|None| |
||
| 140 | |||
| 141 | - io モジュールをユニットテストで活用する |
||
| 142 | - ファイルオブジェクトの代わりに使用 |
||
| 143 | - 標準出力などをキャプチャして比較 |
||
| 144 | - `unittest.mock.patch` でうまく使用できる |
||
| 145 | |||
| 146 | ## 10.3インタープリターに関わる情報を取得、操作する sys |
||
| 147 | Python インタープリターが使用する変数、インタープリター動作に関する関数 |
||
| 148 | |||
| 149 | - コマンドライン引数を取得する argv |
||
| 150 | - `sys.argv` 実行時の引数がリストで保持されている |
||
| 151 | - `argv[0]` は、指定ファイル名 (実行時に指定したままの文字列) |
||
| 152 | |||
| 153 | ```python |
||
| 154 | # exampe.py |
||
| 155 | |||
| 156 | import sys |
||
| 157 | print(sys.argv) |
||
| 158 | ``` |
||
| 159 | |||
| 160 | ```python |
||
| 161 | > python example.py -a AAA -b -c 5 |
||
| 162 | ['example.py', '-a', 'AAA', '-b', '-c', '5'] |
||
| 163 | ``` |
||
| 164 | |||
| 165 | - ライブラリのインポートパスを操作する path |
||
| 166 | - `sys.path` インポート対象のライブラリやパッケージを検索するパスを格納したリスト |
||
| 167 | - ファイルパスを追加することで、import 可能なパッケージやモジュールを動的に変更できる |
||
| 168 | - 初期化は以下の順に行われる |
||
| 169 | - 実行された Python スクリプトのあるパス or 空文字列 (対話モード) |
||
| 170 | - 環境変数 `PYTHONPATH` に設定されたパス |
||
| 171 | - Python のインストール先 |
||
| 172 | - モジュールはリストの先頭のパスから順に検索され、最初に見つかったものがインポートされる (つまり、同名モジュールがあっても、リストの後ろにあるとインポートされない) |
||
| 173 | |||
| 174 | - プログラムを終了する exit() |
||
| 175 | - `sys.exit()` 呼び出した時点で Python スクリプトの実効を終了する関数 |
||
| 176 | - `exit([arg])` |
||
| 177 | - `arg` 数値または任意のオブジェクト |
||
| 178 | - 数値を指定すると、それを終了コードとする (未指定だと 0 扱い) |
||
| 179 | - 数値以外を指定すると、オブジェクトを文字列として `sys.stderr` へ出力し、終了コードは 1 となる |
||
| 180 | |||
| 181 | - コンソールへの入出力を扱う stdin, stdout, stderr |
||
| 182 | |||
| 183 | |オブジェクト|解説|タイプ| |
||
| 184 | |---|---|---| |
||
| 185 | |`sys.stdin`|標準入力|読み込み専用| |
||
| 186 | |`sys.stdout`|標準出力|書き込み専用| |
||
| 187 | |`sys.stderr`|標準エラー出力|書き込み専用| |
||
| 188 | |||
| 189 | ```python |
||
| 190 | >>> sys.stdout.write('standard output message\n') |
||
| 191 | standard output message # 標準出力された文字列 |
||
| 192 | 24 # write()メソッドの戻り値 |
||
| 193 | >>> sys.stderr.write('standard error message\n') |
||
| 194 | standard error message # 標準エラー出力された文字列 |
||
| 195 | 23 # write()メソッドの戻り値 |
||
| 196 | >>> sys.stdin.write('standard input message?\n') |
||
| 197 | Traceback (most recent call last): # 標準入力オブジェクトは読み込み専用のため、書き込みは失敗する |
||
| 198 | File "<stdin>", line 1, in <module> |
||
| 199 | io.UnsupportedOperation: not writable |
||
| 200 | >>> sys.stdin.read() |
||
| 201 | standard input message # 端末に任意の文字列を入力して改行 |
||
| 202 | 'standard output message\n' # Ctrl+D(EOF)が入力されると、read()が受け取った値を返す (Windows だと Ctrl+Z か) |
||
| 203 | ``` |
||
| 204 | |||
| 205 | - breakpoint() 実行時のフック関数 breakpointhook() |
||
| 206 | - `sys.breakpointhook()` |
||
| 207 | - 組み込み関数 `breakpoint()` でデバッグを開始した際に呼ばれるフック関数 |
||
| 208 | - (breakpoint() : 第17章) |
||
| 209 | |||
| 210 | - Python のバージョン番号を調べる version_info |
||
| 211 | - `sys.version_info` バージョン番号を表す 5 要素タプル |
||
| 212 | - `major` `minor` `micro` `releaselevel` `serial` |
||
| 213 | - `releaselevel` 以外は整数 (releaselevel は基本的に文字列か) |
||
| 214 | |||
| 215 | ## 10.4 コマンドラインオプション、引数を扱う argparse |
||
| 216 | |||
| 217 | - コマンドラインオプションを扱う |
||
| 218 | - `ArgumentParser()` |
||
| 219 | |引数名|解説|デフォルト値| |
||
| 220 | |---|---|---| |
||
| 221 | |`prog`|プログラム名|`sys.args[0]`| |
||
| 222 | |`usage`|プログラム利用方法|パーサー指定した引数から自動生成| |
||
| 223 | |`description`|引数のヘルプの前に表示される文字列|`None`| |
||
| 224 | |`epilog`|引数のヘルプの後に表示される文字列|`None`| |
||
| 225 | |`parents`|ArgumentParser オブジェクトのリストを指定すると、そこに含まれる引数が追加される|`[]`| |
||
| 226 | |`formatter_class`|ヘルプとして表示されるフォーマットをカスタマイズするためのクラス|`argparse.HelpFormatter`| |
||
| 227 | |`prefix_chars`|引数の先頭の文字を指定する|`-`| |
||
| 228 | |`fromfile_from_chars`|引数をファイル指定して読み込む際に、フファイルの前に付ける文字を指定|`None`| |
||
| 229 | |||
| 230 | - `add_argument()` |
||
| 231 | - `parse_args()` |
||
| 232 | |||
| 233 | ```python |
||
| 234 | # repeat.py |
||
| 235 | |||
| 236 | import argparse |
||
| 237 | |||
| 238 | # パーサーのインスタンスを作成 |
||
| 239 | parser = argparse.ArgumentParser(description='Example command') |
||
| 240 | # 文字列を受け取る-sオプションを定義 |
||
| 241 | parser.add_argument('-s', '--string', type=str, help='string to display', required=True) |
||
| 242 | # 数値を受け取る-nオプションを定義 |
||
| 243 | parser.add_argument('-n', '--num', type=int, help='number of times repeatedly display the string', default=2) |
||
| 244 | # 引数をパースし、得られた値を変数に格納する |
||
| 245 | args = parser.parse_args() |
||
| 246 | |||
| 247 | # パースによって得られた値を扱う |
||
| 248 | print(args.string * args.num) |
||
| 249 | ``` |
||
| 250 | |||
| 251 | - 実行例 |
||
| 252 | - `-h` オプションは、`ArgumentParser()` によって自動生成される |
||
| 253 | - 必須オプションが無いとエラーが発生する |
||
| 254 | |||
| 255 | ```powershell |
||
| 256 | > python repeat.py |
||
| 257 | usage: repeat.py [-h] -s STRING [-n NUM] |
||
| 258 | repeat.py: error: the following arguments are required: -s/--string |
||
| 259 | > python repeat.py -h |
||
| 260 | usage: repeat.py [-h] -s STRING [-n NUM] |
||
| 261 | |||
| 262 | Example command |
||
| 263 | |||
| 264 | options: |
||
| 265 | -h, --help show this help message and exit |
||
| 266 | -s, --string STRING string to display |
||
| 267 | -n, --num NUM number of times repeatedly display the string |
||
| 268 | ``` |
||
| 269 | |||
| 270 | - 引数指定実行 |
||
| 271 | |||
| 272 | ```powershell |
||
| 273 | > python repeat.py -s "Hey! " |
||
| 274 | Hey! Hey! |
||
| 275 | > python repeat.py -s "Hey! " -n 5 |
||
| 276 | Hey! Hey! Hey! Hey! Hey! |
||
| 277 | ``` |