✏️
python3エンジニア認定実践試験対策②
はじめに
- Python実践レシピに沿って学習します。
以前の記事
-
Python3エンジニア認定実践試験対策①
第4章pythonのクラス、第6章テキストの処理
今回の範囲
章 | タイトル | 問題数 | 問題割合 | 備考 |
---|---|---|---|---|
10 | 汎用OS・ランタイムサービス | 2 | 5.0% | |
11 | ファイルとディレクトリへのアクセス | 2 | 5.0% |
10:汎用OS・ランタイムサービス
モジュール一覧
- osモジュール
- ioモジュール
- sysモジュール
- argparseモジュール
主観と練習問題を見た感覚だとos、sysの方が出現割合が高そうなので、os/sys -> io/argparseの順で覚えてもいいかも
osモジュール
-実行中のプロセス属性の操作、ファイルとディレクトリの操作などOSが提供する様々な機能を利用できる
実行中のプロセス属性の操作
プロセス属性 | 関数 |
---|---|
環境変数 | environ, getenv(), ... |
ユーザーID | getuid(), setuid(), geteuid(), seteuid(), ... |
グループID | getgid(), setuid(), getgroups(), setgroups(), ... |
プロセスID | getqid(), getpgid(), getppid(), ... |
import os
current_env = os.environ
# 環境変数の辞書: 例 {'PATH': '/usr/bin', 'HOME': '/home/user', ...}
path_var = os.getenv('PATH')
# 'PATH'環境変数の値: 例 '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin'
user_id = os.getuid()
# 実行中のプロセスのユーザーID: 通常は 1000 などの数値(Unixのみ)
os.setuid(0) # スーパーユーザー(root)に切り替える(実際の使用には注意が必要)
# プロセスのユーザーIDを変更
effective_user_id = os.geteuid()
# 実行中のプロセスの実効ユーザーID(Unixのみ)
os.seteuid(0) # スーパーユーザー(root)に切り替える(実際の使用には注意が必要)
# 実効ユーザーIDを変更
group_id = os.getgid()
# 実行中のプロセスのグループID: 通常はグループ設定に依存(Unixのみ)
os.setgid(0)
# グループIDを変更する(権限が必要)
groups = os.getgroups()
# ユーザーが属するすべての補助グループのリスト(Unixのみ)
os.setgroups(groups)
# 新しいグループIDのリストを設定する(特権が必要)
current_pid = os.getpid()
# 現在のプロセスID, 例: 23456
parent_pid = os.getppid()
# 親プロセスID
ファイル操作関連の関数
関数名 | 解説 | 戻り値 | pathlibモジュールにある同等の関数 |
---|---|---|---|
chdir(path) | 現在の作業ディレクトリをpathに設定する | None | - |
chmod(path, mode, *, dir_fd=None, follow_symlinks=True) | pathで指定されたファイルまたはディレクトリのモードを変更する | None | Path.chmod() |
getcwd() | 現在の作業ディレクトリを返す | str | Path.cwd() |
listdir(path=".") | pathで指定されたディレクトリ内のファイルとディレクトリを返す | list | Path.iterdir() |
mkdir(name, mode=0o777, *, dir_fd=None) | pathで指定されたディレクトリを作成する | None | Path.mkdir() |
makedirs(name, mode=0o777, exist_ok=False) | nameで指定されたディレクトリを再帰的に作成する。末端のディレクトリだけでなく、中間ディレクトリも作成する。 | None | Path.mkdir() |
remove(path, *, dir_fd=None) | pathで指定されたファイルを削除する。ディレクトリの場合はOSErrorが送出される。 | None | Path.unlink() |
removedirs(name) | nameで指定されたディレクトリをパスの末端から再帰的に削除する | None | - |
rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) | ファイルまたはディレクトリのパスをsrcからdstに変更する | None | Path.rename() |
rmdir(path, *, dir_fd=None) | pathで指定されたディレクトリを削除する。ディレクトリが空でない場合はOSErrorを送出する | None | Path.rmdir() |
import os
# 現在の作業ディレクトリを表示
initial_dir = os.getcwd()
# 最初のディレクトリ: 例 '/home/user/current_working_directory'
# 新しいディレクトリを作成
new_dir = 'test_directory'
os.mkdir(new_dir)
# ディレクトリ 'test_directory' を作成
# 作業ディレクトリを新しいディレクトリに変更
os.chdir(new_dir)
current_dir = os.getcwd()
# 現在のディレクトリ: 例 '/home/user/current_working_directory/test_directory'
# サブディレクトリを作成
sub_dirs = 'subdir1/subdir2/subdir3'
os.makedirs(sub_dirs)
# ディレクトリの階層 'subdir1/subdir2/subdir3' を作成
# 現在のディレクトリの内容をリスト
contents = os.listdir('.')
# 現在のディレクトリの内容: ['subdir1']
# 新しいファイルを作成
file_name = 'sample.txt'
with open(file_name, 'w') as f:
f.write("このファイルはテスト用です。")
#ファイル 'sample.txt' を作成
# ファイルのパーミッションを変更
os.chmod(file_name, 0o444)
# ファイル 'sample.txt' のパーミッションを読み取り専用に変更
# ファイルの名前を変更
new_file_name = 'renamed_sample.txt'
os.rename(file_name, new_file_name)
# ファイル名を 'sample.txt' から 'renamed_sample.txt' に変更
# ファイルを削除
os.remove(new_file_name)
# ファイル 'renamed_sample.txt' を削除
# サブディレクトリを削除 (空の場合)
os.removedirs(sub_dirs)
# サブディレクトリ 'subdir1/subdir2/subdir3' を削除
# 作業ディレクトリを親ディレクトリに戻し、空のディレクトリを削除
os.chdir('..')
os.rmdir(new_dir)
# ディレクトリ 'test_directory' を削除
# 最後に現在のディレクトリを表示
final_dir = os.getcwd()
# 現在のディレクトリ: 例 '/home/user/current_working_directory'
sysモジュール
- Pythonインタープリターが使用する変数や、インタープリターの動作に関連する関数を提供
sysモジュールな主な用途
ライブラリのインポートパスを操作する
- sys.path
インポート対象のモジュールやパッケージを探索する先となるファイルパスを格納したリスト
sys.pathにファイルパスを追加することで、そのファイルパスに置かれたPythonパッケージやモジュールをimport文でインポートできる。
# モジュールの検索パスを取得して表示
# 現在のモジュール検索パス
current_paths = sys.path
# 例: ['/usr/bin', '/some/other/path', ...]
# 新しいパスを追加
sys.path.append('/my/custom/path')
# 新しいパスを追加後のモジュール検索パス
updated_paths = sys.path
# 例: ['/usr/bin', '/some/other/path', ..., '/my/custom/path']
プログラムを終了する
- sys.exit()
Pythonを終了します。
sys.exit(1)
# プログラムを終了します(終了コード1)
コンソールの入出力を扱う
- sys.stdin
標準入力のオブジェクト - sys.stdout
標準出力のオブジェクト - sys.stderr
標準エラー出力のオブジェクト
# 標準入力から1行読み込む
# input_line = sys.stdin
# 例: "Hello, World!" と入力した場合 -> 入力された内容: Hello, World!
# 標準出力に出力します (通常のprint関数はsys.stdoutを使用)
sys.stdout.write("標準出力に直接書き込みました。\n")
# 標準出力に '標準出力に直接書き込みました。' と表示
# 標準エラー出力に出力
sys.stderr.write("これはエラーメッセージです。\n")
# 標準エラーに 'これはエラーメッセージです。' と表示
sysモジュールを用いてprint()とinput()を置き換えることができる
sys.stdout.write() # print()と同じ動作。ただし、改行は入らない
sys.stdin.read() # input()と同じ動作。ただし、入力終了方法がCtrl+D
11: ファイルとディレクトリへのアクセス
Pathオブジェクト、tempfileモジュール、shutilモジュールがバランスよく出題されそう。
Pathオブジェクト
関数名 | 解説 | 戻り値 |
---|---|---|
Path.cwd() | 現在のディレクトリを表すパスオブジェクトを返す。クラスメソッド | パスオブジェクト |
Path.home() | ユーザーのホームディレクトリを表すパスオブジェクトを返す。クラスメソッド | パスオブジェクト |
Path.chmod(mode) | パスのパーミッションを変更する | None |
Path.exists() | パスが存在する場合にTrueを返す | bool |
Path.glob(pattern) | パスが指すディレクトリ以下のpatternに一致するファイルやディレクトリの一覧を、パスオブジェクトとして返すジェネレーターを返す | ジェネレーター |
Path.is_dir() | パスがディレクトリである場合にTrueを返す | bool |
Path.is_file() | パスがファイルである場合にTrueを返す | bool |
Path.iterdir() | パス以下に存在するファイルやディレクトリの一覧を、パスオブジェクトとして返すジェネレーターを返す | ジェネレーター |
Path.mkdir(mode=0o777, parents=False, exist_ok=False) | パスを新しいディレクトリとして返す | None |
Path.open(mode="r", buffering=-1, encoding=None, errors=None, newline=None) | 組み込み関数open()と同様にファイルを開く | ファイルオブジェクト |
Path.rename(target) | パスの名前を変更する。引数targetには文字列かほかのパスオブジェクトを指定する | None |
Path.rmdir() | パスが指すディレクトリを削除する。ディレクトリは空の必要がある | None |
Path.touch(mode=0o666, exist_ok=True) | パスにファイルが存在しなければファイルを作成する。ファイルが存在すれば更新日時を現在日時に変更する | None |
Path.unlink(missing_ok=False) | パスのファイルを削除する | None |
from pathlib import Path
current_path = Path.cwd()
# 現在の作業ディレクトリ: 例 '/home/user/current_working_directory'
home_path = Path.home()
# ユーザのホームディレクトリ: 例 '/home/user'
test_dir = Path('test_directory')
test_dir.mkdir(exist_ok=True)
# 'test_directory'が作成される(既に存在する場合は何もしない)
test_file = test_dir / 'sample.txt'
test_file.touch()
# 'test_directory/sample.txt'が作成される(既に存在する場合は何もしない)
exists = test_file.exists()
# 'sample.txt'は存在するのでTrue
is_directory = test_dir.is_dir()
# 'test_directory'はディレクトリなのでTrue
is_file = test_file.is_file()
# 'sample.txt'はファイルなのでTrue
dir_contents = list(test_dir.iterdir())
# ディレクトリ内のコンテンツをリスト化: 例 [PosixPath('sample.txt')]
test_file.chmod(0o444)
# 'sample.txt'のパーミッションが読み取り専用に変更される
with test_file.open('w', encoding='utf-8') as f:
f.write("これはテスト用のファイルです。")
# 'sample.txt'にテキストが書き込まれる
new_test_file = test_dir / 'renamed_sample.txt'
test_file.rename(new_test_file)
# 'sample.txt'が 'renamed_sample.txt' にリネームされる
new_test_file.unlink()
# 'renamed_sample.txt'が削除される
test_dir.rmdir()
# 'test_directory'が削除される(ディレクトリが空の場合)
tempfileモジュール
一時ファイルおよび一時ディレクトリを作成する機能を提供
with文と一緒に使うことで自動的に後処理を実行してくれる
tempfileモジュールが提供する呼び出し可能オブジェクト
呼び出し可能オブジェクト | 解説 |
---|---|
TemporaryFile() | ファイル名のない一時ファイルをディスク上に作成する |
NamedTemporaryFile() | ファイル名がある一時ファイルをディスク上に作成する |
SpooledTemporaryFile() | 一定ファイルサイズまではデータはメモリ上で処理され、それを超えるとディスクに書き出される一時ファイルを作成する |
TemporaryDirectory() | 一時ディレクトリを作成する |
import tempfile
import os
with tempfile.TemporaryFile() as tmpf:
# バイナリモードで書き込み
tmpf.write(b'Hello, World!')
# ファイルの先頭に戻る
tmpf.seek(0)
# 内容を読み取る
print(tmpf.read()) # 出力: b'Hello, World!'
with tempfile.NamedTemporaryFile(delete=True) as tmpf:
print('Temporary file name:', tmpf.name) # 一時ファイルの名前を表示
tmpf.write(b'Named temporary file example.')
tmpf.seek(0)
print(tmpf.read()) # 出力: b'Named temporary file example.'
# 上記のブロックを抜けるとファイルは自動的に削除されます
with tempfile.SpooledTemporaryFile(max_size=100) as tmpf:
tmpf.write(b'Spool example data that fits in memory.')
tmpf.seek(0)
print(tmpf.read()) # 出力: b'Spool example data that fits in memory.'
# データ量が増えると自動的にディスクに書き込まれる
tmpf.write(b'A' * 101)
tmpf.seek(0)
print(tmpf.read()) # データは引き続き読み取れる
with tempfile.TemporaryDirectory() as tmpdirname:
print('Temporary directory created:', tmpdirname)
# 一時ディレクトリ内にファイルを作成
temp_file_path = os.path.join(tmpdirname, 'example.txt')
with open(temp_file_path, 'w') as file:
file.write('This is a temporary file inside a temporary directory.')
# ファイルが正しく書き込まれたか確認
with open(temp_file_path, 'r') as file:
print(file.read())
shutilモジュール
ディレクトリ、ファイルおよびアーカイブファイルに対して高水準な操作を提供
ファイルコピー系の関数
関数名 | 解説 | 戻り値 |
---|---|---|
copyfile(src, dst, *, follow_symlinks=True) | ファイルsrcをファイルを指すdstにコピーする。dstにディレクトリを指定できない | str |
copy(src, dst, *, follow_symlinks=True) | copyfile()と同様にファイルをコピーし、ファイルのパーミッションもコピーする。dstにディレクトリを指定できる | str |
copy2(src, dst, *, follow_symlinks=True) | copy()と同等の機能に加えて、全てのメタデータを保持しようとする。dstにディレクトリを指定できる | str |
copymode(src, dst, *, follow_symlinks=True) | パーミッションをsrcからdstにコピーする | None |
copystat(src, dst, *, follow_symlinks=True) | パーミッション、最終アクセス時間、最終変更時間やその他のファイル情報をsrcからdstにコピーする | None |
import shutil
from pathlib import Path
# テスト用のファイルとディレクトリを準備
src_file = Path('src.txt')
src_file.write_text('テスト用のファイルです。')
# 'src.txt'が作成され、"テスト用のファイルです。" が書き込まれる
dst_file = Path('dst.txt')
# 'dst.txt'はまだ存在しない
src_dir = Path('src_dir')
src_dir.mkdir(exist_ok=True)
# 'src_dir'ディレクトリが作成される
dst_dir = Path('dst_dir')
shutil.copyfile(src_file, dst_file)
# 'src.txt'を 'dst.txt' に内容をコピー
shutil.copy(src_file, src_dir)
# 'src.txt'を 'src_dir'ディレクトリにコピー
shutil.copy2(src_file, src_dir / 'src_copy2.txt')
# 'src.txt'を 'src_copy2.txt'として 'src_dir'にメタデータごとコピー
shutil.copymode(src_file, dst_file)
# 'src.txt'のパーミッションモードを 'dst.txt'にコピー
shutil.copystat(src_file, dst_file)
# 'src.txt'のステータス情報(パーミッション、タイムスタンプなど)を 'dst.txt'にコピー
再帰的な操作を行う関数
ディレクトリ以下を再帰的にコピー
- copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=True)
- src: コピー対象のディレクトリのパスを指定する。
- dst: コピー後のディレクトリのパスを指定する。既にある場合は例外を送出する。
- dirs_exist_ok:Trueを指定すると、コピー先のディレクトリが存在してもエラーにならない。
shutil.ignore_pattrns()と組み合わせて特定の拡張子のファイルをコピー対象から除外するなど使い方は様々
shutil.copytree(src_dir, dst_dir)
# 'src_dir'内のすべてのファイルを 'dst_dir'としてディープコピー
ignore = shutil.ignore_pattrns(*.png, *.jpg)
shutil.copytree("./from", "./to", ignore=ignore)
関数名 | 解説 | 戻り値 |
---|---|---|
rmtree(path, ignore_errors=False, onerror=None) | pathで指定したディレクトリ以下のファイルをすべて削除する | None |
move(src, dst, copy_function=copy2) | srcディレクトリ以下のファイルを再帰的にdstに移動する。コピー時に使用する関数を指定できる(デフォルトはcopy2) | str |
shutil.rmtree(src_dir)
# 'src_dir'とその中身全部を削除
shutil.move(str(dst_file), str(dst_dir / 'moved_dst.txt'))
# 'dst.txt'を 'dst_dir/moved_dst.txt' に移動
Discussion