11章学習記録 » 履歴 » バージョン 1
Tatsuya ISHIGAKI, 2025/07/24 12:25
| 1 | 1 | Tatsuya ISHIGAKI | # 第11章 ファイルとディレクトリへのアクセス |
|---|---|---|---|
| 2 | |||
| 3 | ## 11.1 ファイルパス操作を直感的に行う pathlib |
||
| 4 | `pathlib` モジュールは、I/O を伴わない機能を提供する **純粋パス (pure path)** と、I/O を伴う機能を提供する **具象パス (concrete path)** を提供する |
||
| 5 | |||
| 6 | - クラス構成 |
||
| 7 | |||
| 8 | |クラス名|解説|基底クラス| |
||
| 9 | |---|---|---| |
||
| 10 | |`PurePath`|純粋パスクラスの基底クラス|なし| |
||
| 11 | |`PurePosixPath`|非 Windows 向けの純粋パスクラス|`PurePath`| |
||
| 12 | |`PureWindowsPath`|Windows 向けの純粋パスクラス|`PurePath`| |
||
| 13 | |`Path`|具象パスクラスの基底クラス|`PurePath`| |
||
| 14 | |`PosixPath`|非 Windows 向けの具象パスクラス|`Path` `PurePosixPath`| |
||
| 15 | |`WindowsPath`|Windows 向けの具象パスクラス|`Path` `PureWindowsPath`| |
||
| 16 | |||
| 17 | - Path オブジェクト (PurePath, Path) 共通 |
||
| 18 | - Path オブジェクト (`PurePath` `Path` インスタンス) の生成には、`PurePath` `Path` に **文字列または他のPathオブジェクト** を渡す |
||
| 19 | - 複数の引数を指定した場合は、それらを連結したオブジェクトが生成される |
||
| 20 | - `PurePath` を使ってインスタンス生成するだけで、環境に合わせて `PurePosixPath` または `PureWindowsPath` のインスタンスが生成される |
||
| 21 | - `Path` についても同様に、`PosixPath` `WindowsPath` が生成される |
||
| 22 | - Path オブジェクト同士、Path オブジェクトと文字列は演算子 `/` が使用可能で、接続されたパスを持つ Path オブジェクトを返す |
||
| 23 | |||
| 24 | - 純粋パスを扱う PurePath |
||
| 25 | |||
| 26 | ```python |
||
| 27 | >>> from pathlib import PurePath, Path |
||
| 28 | >>> PurePath("hello.txt") |
||
| 29 | PureWindowsPath('hello.txt') |
||
| 30 | >>> PurePath("words", "greeting", "hello.txt") # 複数文字列指定 |
||
| 31 | PureWindowsPath('words/greeting/hello.txt') |
||
| 32 | >>> PurePath(Path("japanese"), "greeting", "ohayo.txt") # Pathオブジェクト指定 |
||
| 33 | PureWindowsPath('japanese/greeting/ohayo.txt') |
||
| 34 | >>> PurePath() # 指定無しはカレントディレクトリ |
||
| 35 | PureWindowsPath('.') |
||
| 36 | |||
| 37 | # 演算子 `/` による接続パスのオブジェクト生成 |
||
| 38 | >>> p = PurePath("japanese","greeting") |
||
| 39 | >>> p |
||
| 40 | PureWindowsPath('japanese/greeting') |
||
| 41 | >>> p / "konnichiwa.txt" |
||
| 42 | PureWindowsPath('japanese/greeting/konnichiwa.txt') |
||
| 43 | >>> "all" / p |
||
| 44 | PureWindowsPath('all/japanese/greeting') |
||
| 45 | >>> q = PurePath("night", "oyasumi.txt") |
||
| 46 | >>> q |
||
| 47 | PureWindowsPath('night/oyasumi.txt') |
||
| 48 | >>> p / q |
||
| 49 | PureWindowsPath('japanese/greeting/night/oyasumi.txt') |
||
| 50 | ``` |
||
| 51 | |||
| 52 | - PurePath のプロパティ |
||
| 53 | |||
| 54 | |プロパティ名|解説|戻り値| |
||
| 55 | |---|---|---| |
||
| 56 | |`parts`|パスの各要素のタプル|tuple| |
||
| 57 | |`drive`|ドライブを表す文字列<br>`C:` など<br>UNC共有名もドライブ扱い|str| |
||
| 58 | |`root`|ルートを表す文字列<br>`/` `\\` など|str| |
||
| 59 | |`anchor`|ドライブとルートを結合した文字列|str| |
||
| 60 | |`parents`|上位パスのシーケンス|Path オブジェクトのシーケンス| |
||
| 61 | |`parent`|直接の上位パス|Path オブジェクト| |
||
| 62 | |`name`|パス要素の末尾を表す文字列|str| |
||
| 63 | |`suffix`|末尾の要素の拡張子(ドット含む)<br>一番後ろの拡張子のみ|str| |
||
| 64 | |`suffixes`|末尾の要素の拡張子リスト|list| |
||
| 65 | |`stem`|末尾の要素から拡張子を除外した文字列<br>一番後ろの拡張子のみ除外する|str| |
||
| 66 | |||
| 67 | ```python |
||
| 68 | >>> from pathlib import PurePath, PureWindowsPath |
||
| 69 | >>> p = PurePath('/spam/ham/egg.tar.gz') |
||
| 70 | >>> p.parts # 各要素を取得 |
||
| 71 | ('/', 'spam', 'ham', 'egg.tar.gz') |
||
| 72 | >>> wp = PureWindowsPath('c:/Program Files/spam/ham.exe') |
||
| 73 | >>> wp.parts |
||
| 74 | ('c:\\', 'Program Files', 'spam', 'ham.exe') |
||
| 75 | >>> p.drive # ドライブを取得 |
||
| 76 | '' |
||
| 77 | >>> wp.drive |
||
| 78 | 'c:' |
||
| 79 | >>> p.root # ルートを取得 |
||
| 80 | '/' |
||
| 81 | >>> wp.root |
||
| 82 | '\\' |
||
| 83 | >>> wp.anchor # ドライブとルートを結合した文字列を取得 |
||
| 84 | 'c:\\' |
||
| 85 | >>> for parent in p.parents: # 上位のパスのシーケンスを取得 |
||
| 86 | ... parent |
||
| 87 | ... |
||
| 88 | PurePosixPath('/spam/ham') |
||
| 89 | PurePosixPath('/spam') |
||
| 90 | PurePosixPath('/') |
||
| 91 | >>> p.parent # 直接の上位のパスを取得 |
||
| 92 | PurePosixPath('/spam/ham') |
||
| 93 | >>> p.name # 末尾の要素を取得 |
||
| 94 | 'egg.tar.gz' |
||
| 95 | >>> p.suffix # 拡張子を取得 |
||
| 96 | '.gz' |
||
| 97 | >>> p.suffixes # 拡張子のリストを取得 |
||
| 98 | ['.tar', '.gz'] |
||
| 99 | >>> p.stem # 末尾の要素から拡張子を除いたものを取得 |
||
| 100 | 'egg.tar' |
||
| 101 | ``` |
||
| 102 | |||
| 103 | - PurePath のメソッド |
||
| 104 | |||
| 105 | |メソッド名|解説|戻り値| |
||
| 106 | |---|---|---| |
||
| 107 | |`is_absolute()`|絶対パスの場合 True|bool| |
||
| 108 | |`is_relative_to(*other)`|`other` に対して相対なら True<br>(`other` がこのパス、またはこのパスの parents 要素と一致すれば True)|bool| |
||
| 109 | |`match(pattern)`|glob 形式の `pattern` と一致すれば True|bool| |
||
| 110 | |`with_name(name)`|パスの name 部分を引数 `name` で置換したパス|Path オブジェクト| |
||
| 111 | |`with_stem(stem)`|パスの stem 部分を引数 `stem` で置換したパス|Path オブジェクト| |
||
| 112 | |`with_suffix(suffix)`|パスの suffix 部分を引数 `suffix` で置換したパス|Path オブジェクト| |
||
| 113 | |||
| 114 | ```python |
||
| 115 | >>> from pathlib import PurePath |
||
| 116 | >>> p1 = PurePath('/spam/ham/eggs.txt') |
||
| 117 | >>> p2 = PurePath('eggs.txt') |
||
| 118 | >>> p1.is_absolute() # 絶対パスか |
||
| 119 | True |
||
| 120 | >>> p2.is_absolute() |
||
| 121 | False |
||
| 122 | >>> p1.is_relative_to('/spam') # 指定したパスに対して相対か |
||
| 123 | True |
||
| 124 | >>> p1.is_relative_to('/ham') # 指定したパスに対して相対か |
||
| 125 | False |
||
| 126 | >>> p1.match('*.txt') # パターンに一致するか |
||
| 127 | True |
||
| 128 | >>> p1.with_name('hoge.txt') # nameを変更(eggs.txt→hoge.txt) |
||
| 129 | PurePosixPath('/spam/ham/hoge.txt') |
||
| 130 | >>> p1.with_stem('fuga') # stemを変更(eggs→fuga) |
||
| 131 | PurePosixPath('/spam/ham/fuga.txt') |
||
| 132 | >>> p1.with_suffix('.py') # 拡張子を変更(.txt→.py) |
||
| 133 | PurePosixPath('/spam/ham/eggs.py') |
||
| 134 | >>> p1.with_suffix('') # 拡張子を削除 |
||
| 135 | PurePosixPath('/spam/ham/eggs') |
||
| 136 | ``` |
||
| 137 | |||
| 138 | - 具象パスを扱う Path |
||
| 139 | 具象パスの昨日はファイルシステムにアクセスするため、基本的に OS 状に捜査対象のファイルパスが存在する必要がある |
||
| 140 | |||
| 141 | |メソッド名|解説|戻り値| |
||
| 142 | |---|---|---| |
||
| 143 | |`cwd()`|**クラスメソッド**<br>現在のディレクトリを表すオブジェクト|Path オブジェクト| |
||
| 144 | |`home()`|**クラスメソッド**<br>ユーザのホームディレクトリを表すオブジェクト|Path オブジェクト| |
||
| 145 | |`stat()`|ファイルの各種情報|os.stat_result オブジェクト| |
||
| 146 | |`chmod(mode)`|パスのパーミッションを変更|None| |
||
| 147 | |`exists()`|パスが存在する場合 True|bool| |
||
| 148 | |`glob(pattern)`|パスが指すディレクトリ以下で `pattern` に一致するファイルやディレクトリの一覧を返すジェネレーター|ジェネレーター<br>(Path オブジェクト)| |
||
| 149 | |`is_dir()`||bool| |
||
| 150 | |`is_file()`||bool| |
||
| 151 | |`iterdir()`|パス直下のファイルやディレクトリの一覧を返すジェネレーター|ジェネレーター<br>(Path オブジェクト)| |
||
| 152 | |`mkdir(mode=0o777, parents=False, exist_ok=False)`|パスを新しいディレクトリとして作成|None| |
||
| 153 | |`open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)`|組み込み関数 `open()` と同様にファイルを開く|ファイルオブジェクト| |
||
| 154 | |`read_text(encoding=Noen, errors=None)`|ファイル内容をテキストとして返す|str| |
||
| 155 | |`rename(target)`|パスの名前を変更する<br>`target` 文字列または他の Path オブジェクト|None| |
||
| 156 | |`resolve(strict=False)`|パスを絶対パスにし、シンボリックリンクを解決する|Path オブジェクト| |
||
| 157 | |`rmdir()`|パスが指すディレクトリを削除する<br>ディレクトリは空の必要がある|None| |
||
| 158 | |`touch(mode=0o666, exist_ok=True)`|パスのファイルが存在しない場合、作成<br>存在する場合、更新日時を現在日時で更新|None| |
||
| 159 | |`unlink(missing_ok=False)`|パスのファイルを削除する|None| |
||
| 160 | |`write_text(data, encoding=None, errors=None)`|ファイルに `data` を書き込む<br>書き込んだ文字数を返す|int| |
||
| 161 | |||
| 162 | ```python |
||
| 163 | >>> from pathlib import Path |
||
| 164 | >>> Path.cwd() # 現在のディレクトリ |
||
| 165 | PosixPath('/Users/takanori/spam/ham') |
||
| 166 | >>> Path.home() # ホームディレクトリ |
||
| 167 | PosixPath('/Users/takanori') |
||
| 168 | >>> p = 'spam.txt' |
||
| 169 | >>> p.exists() # 存在を確認 |
||
| 170 | True |
||
| 171 | >>> p.stat().st_mode # 状態を取得 |
||
| 172 | 33188 |
||
| 173 | >>> p.chmod(0o600) # パーミッションを変更 |
||
| 174 | >>> p.stat().st_mode |
||
| 175 | 33152 |
||
| 176 | >>> p.is_file() # ファイルかどうか |
||
| 177 | True |
||
| 178 | >>> with p.open(encoding='utf-8') as f: # ファイルを開く |
||
| 179 | ... print(f.read()) |
||
| 180 | ... |
||
| 181 | スパムスパムスパム |
||
| 182 | >>> p.write_text('ハムハムハム', encoding='utf-8') # ファイルに書き込み |
||
| 183 | 6 |
||
| 184 | >>> p.read_text(encoding='utf-8') # ファイルから読み込み |
||
| 185 | 'ハムハムハム' |
||
| 186 | >>> p.unlink() # ファイルを削除 |
||
| 187 | >>> p.exists() |
||
| 188 | False |
||
| 189 | >>> p.touch() # ファイルを作成 |
||
| 190 | >>> p.resolve() # 絶対パスを取得 |
||
| 191 | PosixPath('/Users/takanori/spam/ham/spam.txt') |
||
| 192 | ``` |
||
| 193 | |||
| 194 | - glob(), iterdir() での検索例 |
||
| 195 | |||
| 196 | ``` |
||
| 197 | ./a.py |
||
| 198 | ./b.py |
||
| 199 | ./datas |
||
| 200 | ./datas/c.txt |
||
| 201 | ./datas/d.txt |
||
| 202 | ./readme.txt |
||
| 203 | ``` |
||
| 204 | |||
| 205 | ```python |
||
| 206 | >>> from pathlib import Path |
||
| 207 | >>> p = Path() # 現在のディレクトリのパスオブジェクトを取得 |
||
| 208 | >>> p.iterdir() # iterdir()はジェネレーターを返す |
||
| 209 | <generator object Path.iterdir at 0x7f9f300f7740> |
||
| 210 | >>> sorted(p.iterdir()) # ディレクトリ直下の全オブジェクトを返す |
||
| 211 | [PosixPath('a.py'), PosixPath('b.py'), PosixPath('datas'), PosixPath('readme.txt')] |
||
| 212 | >>> list(p.glob('*.txt')) # *.txtというファイルを返す |
||
| 213 | [PosixPath('readme.txt')] |
||
| 214 | >>> sorted(p.glob('**/*.txt')) # ディレクトリを再帰的にたどって*.txtというファイルを返す |
||
| 215 | [PosixPath('datas/c.txt'), PosixPath('datas/d.txt'), PosixPath('readme.txt')] |
||
| 216 | ``` |
||
| 217 | |||
| 218 | - path-like オブジェクト |
||
| 219 | - 以前は Python でのパス使用は、パス文字列での指定だけだったが、現在は `Path` のような **path-like オブジェクト** が使用できる |
||
| 220 | |||
| 221 | |||
| 222 | path-like オブジェクトに対応する関数、標準ライブラリ |
||
| 223 | |名前|説明| |
||
| 224 | |---|---| |
||
| 225 | |`open()` 関数|ファイルを開く組み込み関数| |
||
| 226 | |`configparser`|設定ファイルのパーサー| |
||
| 227 | |`zipfile`|zip アーカイブファイルの操作| |
||
| 228 | |`sqlite3`|SQLite データベース| |
||
| 229 | |`shutil`|高水準ファイル操作| |
||
| 230 | |`os`|OS のインターフェース| |
||
| 231 | |`os.path`|パスの操作| |
||
| 232 | |||
| 233 | ## 11.2 一時的なファイルやディレクトリを生成する tempfile |
||
| 234 | 作成ユーザのみ読み書き可能なパーミッション、競合しないなど、可能な限り安全なファイル・ディレクトリ生成が行われる |
||
| 235 | |||
| 236 | - 以下の 4 つの呼び出し可能オブジェクトは、コンテキストマネージャーとして with 文で使用可能 |
||
| 237 | |||
| 238 | |呼び出し可能オブジェクト|解説| |
||
| 239 | |---|---| |
||
| 240 | |`TemporaryFile()`|ファイル名の無い一時ファイルを作成| |
||
| 241 | |`NamedTemporaryFile()`|ファイル名がある一時ファイルを作成| |
||
| 242 | |`SpooledTemporaryFile()`|一定サイズまでメモリ上で処理され、超えるとディスク書き出しが行われる一時ファイルを作成| |
||
| 243 | |`TemporaryDirectory()`|一時ディレクトリを作成| |
||
| 244 | |||
| 245 | - `TemporaryFile()` ファイルシステム上に名前を持ったファイルとして生成される保証はない |
||
| 246 | - `NamedTemporaryFile()` ファイルシステム上に名前を持ったファイルとして生成される為、他システム等から参照可能 |
||
| 247 | - これらはそれぞれ適切な一時ファイルインスタンスを返すため、インスタンス型は関数名とは必ずしも一致しない |
||
| 248 | |||
| 249 | - 一時ファイルを作成する |
||
| 250 | - `TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)` |
||
| 251 | - `mode` 一時ファイルオープン時のモード |
||
| 252 | - `buffering` バッファリングポリシー |
||
| 253 | - `0` バッファリング無し (バイナリのみ) |
||
| 254 | - `1` 行単位バッファリング (テキスト書き込みのみ) |
||
| 255 | - `1より大きい整数` 指定値バイトの固定サイズチャンクバッファ |
||
| 256 | - `encoding` 文字エンコード |
||
| 257 | - `newline` |
||
| 258 | - `None` |
||
| 259 | - `''` |
||
| 260 | - `\n` |
||
| 261 | - `\r` |
||
| 262 | - `\r\n` |
||
| 263 | - `suffix` 文字列指定すると、ファイル名の接尾辞として使用される |
||
| 264 | - `prefix` 文字列指定すると、ファイル名の接頭辞として使用される |
||
| 265 | - `dir` ファイルを生成するディレクトリを指定する |
||
| 266 | - デフォルトでは環境変数 `TMPDIR` などの値が採用される |
||
| 267 | - `errors` エンコード、デコード時のエラーの挙動 |
||
| 268 | - `strict` 例外 ValueError を発生させる (`None` も同じ) |
||
| 269 | - `ignore` |
||
| 270 | - `replace` |
||
| 271 | - `surrogateescape` |
||
| 272 | - `xmlcharrefreplace` |
||
| 273 | - `backslashreplace` |
||
| 274 | - `namereplace` |
||
| 275 | - `NamedTemporaryFile()` |
||
| 276 | - (TemporaryFile() と同じ引数あり) |
||
| 277 | - `delete` `delete_on_close` |
||
| 278 | - `delete=True` かつ `delete_on_close=True` (デフォルト) : コンテキストマネージャーでの終了時、ファイルの close 時に実ファイルが削除される |
||
| 279 | - `delete=True` かつ `delete_on_close=False` : コンテキストマネージャーでの終了時 (と file-like オブジェクトが消える際) にのみ実ファイルが削除される |
||
| 280 | - `delete=False` (このとき `delete_on_close` は無視) : 実ファイルの自動削除無し |
||
| 281 | |||
| 282 | ```python |
||
| 283 | >>> with tempfile.TemporaryFile() as temp: |
||
| 284 | ... print(temp) |
||
| 285 | ... temp.write(b"AAA") |
||
| 286 | ... temp.write(b"BBBB") |
||
| 287 | ... temp.seek(0) |
||
| 288 | ... temp.read() |
||
| 289 | ... |
||
| 290 | <tempfile._TemporaryFileWrapper object at 0x0000021A34892490> # 型は "_TemporaryFileWrapper" らしい |
||
| 291 | 3 # write(b"AAA") の返り値(書き込み文字数) |
||
| 292 | 4 # write(b"BBBB") の返り値(書き込み文字数) |
||
| 293 | 0 # seek(0) の返り値(オフセット位置) |
||
| 294 | b'AAABBBB' # read() の返り値 |
||
| 295 | ``` |
||
| 296 | |||
| 297 | - 一時ディレクトリを作成する |
||
| 298 | - `TemporaryDirectory(suffix=None, prefix=None, dir=None)` |
||
| 299 | - `suffix` 文字列指定すると、ディレクトリ名の接尾辞として使用される |
||
| 300 | - `prefix` 文字列指定すると、ディレクトリ名の接頭辞として使用される |
||
| 301 | - `dir` ディレクトリを生成するディレクトリを指定する |
||
| 302 | - コンテキストマネージャーとして実行した場合、as キーワードの引数には **ディレクトリパス文字列** が渡される |
||
| 303 | - コンテキストマネージャーとして試用しなかった場合は TemporaryDirectory インスタンスが返されるが、自分で削除しないといけない... |
||
| 304 | - `pathlib.Path` などで操作 |
||
| 305 | |||
| 306 | ## 11.3 高レベルなファイル操作を行う shutil |
||
| 307 | ディレクトリ、ファイル、およびアーカイブに対して高水準な操作を提供する |
||
| 308 | |||
| 309 | - ファイルをコピーする |
||
| 310 | |||
| 311 | |関数名|解説|戻り値| |
||
| 312 | |---|---|---| |
||
| 313 | |`copyfile(src, dst, *, follow_symlinks=True)`|ファイル `src` をファイル `dst` にコピーする|str| |
||
| 314 | |`copymode(src, dst, *, follow_symlinks=True)`|パーミッションを `src` から `dst` にコピーする|None| |
||
| 315 | |`copystat(src, dst, *, follow_symlinks=True)`|パーミッション、最終アクセス時刻、最終変更時刻やその他のファイル情報を `src` から `dst` にコピーする|None| |
||
| 316 | |`copy(src, dst, *, follow_symlinks=True)`|`copyfile()` + `copymode()`|str| |
||
| 317 | |`(src, dst, *, follow_symlinks=True)`|`copyfile()` + `copystat()`|str| |
||
| 318 | |||
| 319 | - 引数の `src` `dst` にはファイルを表す文字列の他、**path-like オブジェクト** や **Path オブジェクト** も指定可能 |
||
| 320 | - `copyfile()` `copy()` `copy2()` の戻り値は `dst` のパス文字列 |
||
| 321 | - ※ `copy()` `copy2()` の `dst` にはディレクトリを指定可能だが、`copyfile()` はファイルのみ |
||
| 322 | |||
| 323 | ```python |
||
| 324 | >>> shutil.copyfile("testsrc.txt", "testdst.txt") |
||
| 325 | 'testdst.txt' |
||
| 326 | >>> shutil.copy("testsrc.txt", "testdst_copy.txt") |
||
| 327 | 'testdst_copy.txt' |
||
| 328 | >>> shutil.copy2("testsrc.txt", "testdst_copy2.txt") |
||
| 329 | 'testdst_copy2.txt' |
||
| 330 | ``` |
||
| 331 | |||
| 332 | ``` |
||
| 333 | green@cucumber MINGW64 /e/PythonExamPrac/chapter11 |
||
| 334 | $ stat ./testsrc.txt |
||
| 335 | File: ./testsrc.txt |
||
| 336 | Size: 41 Blocks: 1 IO Block: 65536 regular file |
||
| 337 | Device: e2ca7b4dh/3804920653d Inode: 1970324837509872 Links: 1 |
||
| 338 | Access: (0644/-rw-r--r--) Uid: (197610/ green) Gid: (197610/ UNKNOWN) |
||
| 339 | Access: 2025-07-23 21:56:51.628029400 +0900 |
||
| 340 | Modify: 2025-07-23 21:49:51.453832500 +0900 |
||
| 341 | Change: 2025-07-23 21:49:51.453832500 +0900 |
||
| 342 | Birth: 2025-07-23 21:49:08.805897000 +0900 |
||
| 343 | |||
| 344 | green@cucumber MINGW64 /e/PythonExamPrac/chapter11 |
||
| 345 | $ stat ./testdst.txt |
||
| 346 | File: ./testdst.txt |
||
| 347 | Size: 41 Blocks: 1 IO Block: 65536 regular file |
||
| 348 | Device: e2ca7b4dh/3804920653d Inode: 281474977245937 Links: 1 |
||
| 349 | Access: (0644/-rw-r--r--) Uid: (197610/ green) Gid: (197610/ UNKNOWN) |
||
| 350 | Access: 2025-07-23 21:57:01.835098500 +0900 |
||
| 351 | Modify: 2025-07-23 21:54:58.789202300 +0900 |
||
| 352 | Change: 2025-07-23 21:55:04.887191200 +0900 |
||
| 353 | Birth: 2025-07-23 21:54:58.789202300 +0900 |
||
| 354 | |||
| 355 | green@cucumber MINGW64 /e/PythonExamPrac/chapter11 |
||
| 356 | $ stat ./testdst_copy.txt |
||
| 357 | File: ./testdst_copy.txt |
||
| 358 | Size: 41 Blocks: 1 IO Block: 65536 regular file |
||
| 359 | Device: e2ca7b4dh/3804920653d Inode: 281474977245938 Links: 1 |
||
| 360 | Access: (0644/-rw-r--r--) Uid: (197610/ green) Gid: (197610/ UNKNOWN) |
||
| 361 | Access: 2025-07-23 21:56:37.277060300 +0900 |
||
| 362 | Modify: 2025-07-23 21:55:52.996307000 +0900 |
||
| 363 | Change: 2025-07-23 21:55:52.996307000 +0900 |
||
| 364 | Birth: 2025-07-23 21:55:52.996307000 +0900 |
||
| 365 | |||
| 366 | green@cucumber MINGW64 /e/PythonExamPrac/chapter11 |
||
| 367 | $ stat ./testdst_copy2.txt |
||
| 368 | File: ./testdst_copy2.txt |
||
| 369 | Size: 41 Blocks: 1 IO Block: 65536 regular file |
||
| 370 | Device: e2ca7b4dh/3804920653d Inode: 281474977245939 Links: 1 |
||
| 371 | Access: (0644/-rw-r--r--) Uid: (197610/ green) Gid: (197610/ UNKNOWN) |
||
| 372 | Access: 2025-07-23 21:56:37.277060300 +0900 |
||
| 373 | Modify: 2025-07-23 21:49:51.453832500 +0900 |
||
| 374 | Change: 2025-07-23 21:49:51.453832500 +0900 |
||
| 375 | Birth: 2025-07-23 21:56:32.456361500 +0900 |
||
| 376 | ``` |
||
| 377 | |||
| 378 | - 再帰的にディレクトリやファイルを操作する |
||
| 379 | |||
| 380 | |関数名|解説|戻り値| |
||
| 381 | |---|---|---| |
||
| 382 | |`rmtree(path, ignore_errors=False, onerror=None)`|`path` で指定したディレクトリを再帰的に削除<br>配下のファイル、ディレクトリもすべて削除|None| |
||
| 383 | |`move(src, dst, copy_function=copy2)`|`src` ディレクトリ以下のファイルを再帰的に `dst` に移動<br>コピーに使用する関数を指定可能|str| |
||
| 384 | |||
| 385 | - 再帰コピーには copytree() を使用 |
||
| 386 | - `copytree(src, dst, symlinks=False, ignore=None, coy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)` |
||
| 387 | - `src` コピー対象ディレクトリ |
||
| 388 | - `dst` コピー先ディレクトリ (すでに存在する場合は例外送出) |
||
| 389 | - `symlinks` シンボリックリンクの扱い |
||
| 390 | - True : シンボリックファイルのままコピー |
||
| 391 | - False : リンク先のファイルをコピーして配置 |
||
| 392 | - `ignore` コピー対象外ファイルを決定する関数を指定 |
||
| 393 | - shutil.ignore_patterns() を利用すると任意パターンのフィルタが利用できる |
||
| 394 | - `copy_function` コピーに用いる関数を指定 |
||
| 395 | - `ignore_dangling_symlinks` True にすると、引数 symlinks=False の場合にリンク先が存在しなくてもエラーを出さない |
||
| 396 | - `dirs_exist_ok` True にすると、コピー先ディレクトリが存在していてもエラーを出さない |
||
| 397 | - **戻り値** コピー先ディレクトリ名 |
||
| 398 | |||
| 399 | ```bash |
||
| 400 | $ ls ./from |
||
| 401 | a.pyc a.swp a.txt b.txt c.txt d.txt |
||
| 402 | ``` |
||
| 403 | |||
| 404 | ```python |
||
| 405 | >>> import shutil |
||
| 406 | >>> ignore = shutil.ignore_patterns('*.pyc', '*.swp') # 拡張子が.pycと.swpを除外対象にする |
||
| 407 | >>> ignore # ignore(path, names)という呼び出し可能オブジェクト |
||
| 408 | <function ignore_patterns.<locals>._ignore_patterns at 0x7fe7d821aa60> |
||
| 409 | >>> shutil.copytree('./from', './to', ignore=ignore) # fromからtoに再帰的にコピー |
||
| 410 | 'to' |
||
| 411 | ``` |
||
| 412 | |||
| 413 | ```bash |
||
| 414 | $ ls ./to |
||
| 415 | a.txt b.txt c.txt d.txt |
||
| 416 | ``` |