模擬試験実施時メモ1 » 履歴 » リビジョン 2
リビジョン 1 (Tatsuya ISHIGAKI, 2025/08/22 10:08) → リビジョン 2/4 (Tatsuya ISHIGAKI, 2025/08/25 14:14)
# 模擬試験メモ
## 実施模試
- [ExamApp](https://python-basic.com/) 実践/初級
- 時間制限なし
- 40問
## メモ
- pip
- バージョン指定インストール `pip install package==2.0.1`
- バージョンの範囲指定インストール
- `pip install "package<3.0"`
- `pip install "package>=2.0,<3.0"`
- 別バージョンインストール `pip --upgrade install package==1.0.0`
- 短いオプション `pip -U install package==1.0.0`
- 指定バージョンは新旧どちらでもOK (ダウングレードもできる)
- **??** `pip --upgrade install` `pip install --upgrade` 両方の記載があるが、どちらでも良いのか
- アンインストール `pip uninstall package`
- 指定パッケージのみ削除、依存パッケージはアンインストールされない
- flake8
- flake8 はコーディングの静的チェックを、以下の3ツールを使用して行う
- `pycodestyle` PEP8 への準拠チェック
- `Pyflakes` 文法のチェック
- `McCabe` コードの複雑度をチェック
- エラーコード1文字目は使用ツールで変わる
- `E` `W` pycodestyle
- `F` Pyflakes
- `C` McCabe
- 例外処理 try-except
- `try` の後には `except` または `finally` が必須
- `else` を入れる場合は全 `except` の後に記載
- `finally` は必ず最後
- 処理フロー
- `try` で例外発生
- 最初に適合した `except` 節の処理が実行され、存在すれば `finally` 節が実行される
- 適合する `except` 節が無ければ、存在する場合は `finally` 節が実行され、例外は再送出される
- 引数
- 位置引数としての呼び出しでは、仮引数の順に適用
- 実引数にイテラブルを渡すと、位置引数に展開される
- 実引数に `**` を前置した辞書を渡すと、キーワード引数として展開される
- (`**` を前置した仮引数である) 可変数キーワード引数は、辞書として使用する
- イテラブル関連の変換
- `items()` (辞書のメソッド) は、キーとバリューをタプルでまとめたイテレーターを返す
- `enumerate()` 関数は、引数イテラブルに対してインデックスと値をタプルでまとめたイテレーターを返す
- `zip()` 関数は、複数のイテラブルを引数にとり、それらの同一インデックスをタプルにまとめたイテレータを返す
- 引数のうち最短のイテラブルに合わせたタプル数となる
- `split()` (strのメソッド) は、指定文字で分割した文字列リストを返す
- 内包表記
- フィルタを使う場合は `(変数を使って取得値を決める)式 for 変数 in イテラブル if 条件式`
- 例(リスト): `[i * 2 for i in range(10) if i % 2 == 0]`
- → `[0, 4, 8, 12, 16]`
- 各種内包表記
- リスト `[~]`
- 集合 `{~}` (リストと同様で、括弧のみ異なる)
- 辞書 `{key: value for ~}` (集合と同様で、先頭にコロンを使用してキーと値を記述)
- ジェネレーター式 `(~)` (リストと同様で、括弧のみ異なる)
- ジェネレーターなので、値取得の度に値が生成される
- タプルの内包表記は存在しない
- 三項演算子
- Python の三項演算子 `(条件成立時の値) if (条件) else (条件不成立時の値)`
- 例: `"even" if a % 2 == 0 else "odd"`
- 辞書
- `{}` は空の辞書 (集合ではない)
```python
>>> a = {}
>>> type(a)
<class 'dict'>
>>> b = set()
>>> type(b)
<class 'set'>
```
- @property
- インスタンスメソッド (引数 self のみ) に `@property` デコレーターを付けると、`()` 無しで、メソッド呼び出し結果を取得できる
- `@<プロパティ名>.setter` デコレーターによって、値設定も可能
- プロパティ名 (`@property` を付けたメソッド名)
- このメソッドの第2引数で値受け取る `(self, <value>)`
- @classmethod
- インスタンス化せずに呼び出せるメソッド
- 第一引数 (仮引数) としてクラスオブジェクト (インスタンスではない) が暗黙的に渡される
- @staticmethod
- インスタンス化せずに呼び出せるメソッド
- 暗黙的に渡される引数は無い
- @dataclass
- クラスデコレーターとして使用する
- クラスのフィールドへの型ヒントが必須となる
- 厳密には、型ヒントがついたフィールドのみ自動生成されるメソッド (コンストラクタ含む) に反映される
- 型ヒント無しのフィールドも、通常のフィールドとして使用はできる
- `__init__()`, `__repr__()`, `__eq__()` 等が自動で生成される
- 生成されるメソッド (コンストラクタ含む) は、定義時の記述順に従う
- コンストラクタの仮引数が、フィールド記述順になるということ
- フィールドにデフォルト値を指定する場合、コンストラクタの仮引数にもデフォルト値が定義される
- 引数の順番となる為、デフォルト値のあるフィールドは、無いフィールドより後ろに定義する
- コンストラクタへの実引数は、デフォルト値無しのフィールド数が最低限必要となる
- フィールドの型ヒントは、Python の動的型付けの性質上、実行時に型ヒント以外の値が渡されてもエラーにはならない
- 型ヒント
- すべての型ヒントは、動作時の制限にはならない (エラー発生しない)
- mypy などでコードレベルでの静的型チェックでの検査、可読性向上の為の記述となる
- typing モジュールでの型ヒント
- `Union[型1, 型2]` 型1 または 型2
- `Optional[型1]` 型1 または None
- `Any` 任意の型
- `Literal[値1, 値2, 値3]` いづれかの「値」
- typing モジュールその他
- `TypeVar` 型変数の型
- `TypedDict` TypedDict を継承してクラス定義すると、フィールド名文字列をキー、値をその型ヒントの型、とする辞書型 (クラス) を定義したことになる
- TypeDict を継承したクラス定義では、型タイプ無しのフィールド定義があると失敗するみたい
- また、フィールドにデフォルト値を付ける意味は無い様子 (勝手にキーバリューペアが増える、ということは無い)
- (他と同様に、あくまでも型ヒントなので動作時の型不一致でもエラーは発生しない)
- 正規表現 (`re` モジュール)
- 関数 `search(pat, str)`
- パターン pat にマッチする str 中の最初の部分を Match で返す
- マッチしない場合は None を返す
- 関数 `match(pat, str)`
- str の先頭に pat がマッチすれば Match を返す
- マッチしない場合は None を返す
- unicodedata.normalize()
- 関数 `normalize(form, unistr)`
- form には `NFC` `NFKC` `NFD` `NFKD` いずれかを指定 (多くは NFKC でよいはず)
- 文字列メソッドでの変換
- (以下は、全角文字の英字に対しても変換成功する)
- `swapcase()` 大文字と小文字を入れ替える
- `title()` 単語単位で先頭が大文字、他を小文字にする
- `capitalze()` 文字列の先頭だけ大文字、他を小文字にする
```python
>>> "NaMe".swapcase()
'nAmE'
>>> "nAmE".swapcase()
'NaMe'
>>> "my nAmE IS".title()
'My\u3000Name Is'
>>> "my nAmE IS".title()
'My Name Is'
>>> "my nAmE IS".capitalize()
'My name is'
```
- datetime モジュールの datetime クラス
- `now()` は datetime クラスのクラスメソッド
- time モジュール
- モジュールで使用される `struct_time` オブジェクト
- 関数 `sleep(secs)` : secs 秒の間、**現在のスレッドの** 実行を中断する
- async 構文中では期待通りに動かない可能性あり、代わりに `asyncio.sleep()` を使用する
- イテラブル関連関数
- 関数 `sorted()`: イテラブルを昇順ソートした新しいリストを返す
- 引数 `reverse=True` で降順ソート
- 関数 `reversed()`: イテラブルを **逆順** (降順ではない) にした **イテレーター** (リストではない) を返す
- メソッド `list.sort()`: リスト要素をソートする (戻り値は None)
- メソッド `list.reverse()`: リスト要素を逆順にする (戻り値は None)
- **operator** モジュール
- 以下はソートの key 引数に使用する 2 関数
- 関数 `itemgetter()`: インデックス、キーによるソート要素、ソート順の指定
- 関数 `attrgetter()`: (クラスの) 属性によるソート要素、jソート順の指定
- enum
- `enum.Enum` クラスを継承して定義
- フィールドにを列挙値として定義する
- `enum.auto()` で、フィールド値を自動で振ることが可能 (1から順に)
- Class1 なら定数取得は `Class1.FIRST` `Class1['FIRST']` `Class1(1)` (最後のは値から取得)
- 取得した定数は `name` `value` 属性を持つ
- itertools
- `chain()` イテラブルを連結したイテレーターを返す
- `groupby()` イテラブルを key 引数で判定し、連続する値をグループ化したイテレーターを返す
- `list(groupby("aaabba"))`
- → `[('a',【'a' 3回のイテレータ】),('b',【'b' 2回のイテレータ】),('a',【'a' 1回のイテレータ】)]`
- `islice(iter, stop)` `islice(iter, start, stop[, step])`
- 通常のスライスと同様の結果を得られる
- `islice()` ではジェネレーターなどの大きさ不明の対象を扱うことができる
- 大きさ不明を扱えるため、start, stop は 0 以上、step は 1 以上でないとエラーとなるようになっている
- `zip_longest(*iter, fillvalue=None)`
- 組み込みの `zip()` と同様だが、最も長いイテラブルに合わせたイテレーターが返される
- 短いイテラブルの足りない要素の値を埋めるのに、fillvalue の値が使用される
- `product(*iter, repeat=1)`
- デカルト積
- repeat は、イテラブル全体が N 回指定されたのと同じ
- `product(iter1, iter2, repeat=2)` は以下と等価 (各イテレータは毎回同じ列を返すとする)
- `product(iter1, iter2, iter1, iter2)`
```python
>>> pr1 = itertools.product("AB", "12")
>>> for v1, v2 in pr1:
... print(v1+v2)
...
A1
A2
B1
B2
>>> pr2 = itertools.product("AB", "12", repeat=2)
>>> for v1, v2, v3, v4 in pr2:
... print(v1+v2+v3+v4)
...
A1A1
A1A2
A1B1
A1B2
A2A1
A2A2
A2B1
A2B2
B1A1
B1A2
B1B1
B1B2
B2A1
B2A2
B2B1
B2B2
>>> pr3 = itertools.product("AB", repeat=2)
>>> for v1, v2 in pr3:
... print(v1+v2)
...
AA
AB
BA
BB
```
- `permutations(iter, r=None)`
- 長さ r の順列タプルのイテレーターを返す
- r 未指定なら、iter の長さとみなす
- `combinations(iter, r)`
- 長さ r の組合せタプルのイテレーターを返す
- ※インデックスが異なれば別要素とするので、イテラブルに重複あれば、単一の組合せタプルに同一値が入ることはある
- `combinations_with_replacement(iter, r)`
- 長さ r の組合せタプルのイテレーターを返す
- 同一要素 (同一インデックスの要素) を複数回使用する組合せを含む
- copy
- `copy()` 浅いコピー
- リストなどの第1階層のみの値がコピーされ、参照が含まれる場合は参照のまま (コピー元の参照をそのまま) コピーする
- `deepcopy()` 深いコピー
- 再帰的にオブジェクトをコピーする
- os
- `remove()` ファイル削除 (ディレクトリ指定はエラー)
- `rmdir()` 空のディレクトリを削除 (空でなければエラー)
- `removedirs()` ディレクトリを再帰削除
- io
- class `StringIO(initial_value='', newline='\n')`
- メソッド `read(size=-1)` `write(s)` `tell()` `seek(offset, whence=SEEK_SET)` `getvalue()` `close()`
- class `BytesIO([initial_bytes])`
- メソッド `read(size=-1)` `write(s)` `tell()` `seek(offset, whence=SEEK_SET)` `getbuffer()` `getvalue()` `close()`
- `getbuffer()` では実際のバッファを返し、読み書き可能
- `getvalue()` ではバッファ以内を新たなバイト列で返す
- `patch()` の new_callable 引数に `StringIO` `BytesIO` を渡して、IO モックとして活用
- `contextlib.redirect_stdout(new_target)` `contextlib.redirect_stderr(new_target)` に指定して一時的に IO モックとして活用
- sys
- `exit([arg])` 終了ステータス arg (デフォルト 0) で Python 実行を終了
- ※ try-except 内で実行した場合、finally があれば実行されたあとに終了する
- `argv` コマンドライン引数を文字列リストとして保持 (インデックス 0 はファイル名)
- `path` モジュール検索するパスを文字列リストとして保持
- 初期値は
- 実行ディレクトリ (対話型の場合は空文字列)
- 環境変数 **PYTHONPATH** の値
- python インストール先 (標準、インストール済みモジュールの配置場所)
- 実行中の要素追加で、import で検索するパスを追加可能
- `stdin` `stdout` `stderr`
- `breakpoint()` `breakpointhook()`
- デフォルトで `breakpointhook` には pdb デバッガが設定されているが、任意の呼び出し可能オブジェクトを設定可能
- 環境変数 **PYTHONBREAKPOINT** に関数名を渡しても同様の設定となる
- `version_info` python のバージョン情報を 5 要素タプル (名前付きタプル) で保持
- `major` 整数
- `minor` 整数
- `micro` 整数
- `releaselevel` 次のいずれかの文字列 **alpha**, **beta**, **candidate**, **final**
- `serial` 整数
- `sys.stdout.write()` は引数文字列のみ出力、`print()` は改行を加えて出力
- `sys.stdin.read()` は **EOF** で入力完了、`input()` は Enter キーで入力終了
- argparse
- class `ArgumentParser()`
- コンストラクタ引数 `prog` `usage` `description` `epilog` `parents` `formatter_class` `prefix_chars` `fromfile_prefix_chars` `argument_default` `conflict_hander` `add_help` `allow_abbrev` `exit_on_error`
- メソッド `add_argument()`
- `name` ("foo" 等) or `flags` ("-f", "--foo" 両方等)
- pathlib
- `PurePath` `PurePosixPath` `PureWindowsPath`
- `Path` `PosixPath` `WindowsPath`
- パスオブジェクトは `/` (**スラッシュ演算子**) でパスオブジェクト、文字列と結合可能 (結果はパスオブジェクトとなる)
- 演算子の右が絶対パスの場合は、演算子の左は無視される
- Windows の場合 (演算子の左にドライブ文字あり、右にルートからのパスの場合) は、ドライブ文字は保持される
- オブジェクト生成時には Path オブジェクト、パス文字列を任意数渡すことで結合されたパスのオブジェクトが生成される
- パスオブジェクト属性
- `parts`(タプル) `drive` `root` `anchor` `parents` `parent` `name` `suffix` `suffixes` `stem`
- PurePath メソッド
- `is_absolute()` `is_relative_to(*other)` `match(pattern)` `with_name(name)` `with_stem(stem)` `with_suffix(suffix)`
- Path メソッド
- クラスメソッド `cwd()` `home()`
- `stat()` `chmod(mode)` `exists()` `glob(pattern)` `is_dir()` `is_file()` `iterdir()`
- `mkdir()` `open()` `read_text()` `rename(target)`(target はパスオブジェクトでも可) `resolve()` `rmdir()`(空ディレクトリ対象) `touch()` `unlink()`(ファイル削除) `write_text(data)`
- tempfile
- `TemporaryFile()` `NamedTemporaryFile()` `SpooledTemporaryFile()`
- コンテキストマネージャーとして使用すれば、ファイルオブジェクトとして扱える
- with を抜けると、ファイルが閉じられ、削除される
- コンテキストマネージャーとして使用しなかった場合、オブジェクトの `close()` で閉じる
- `TemporaryDirectory()`
- コンテキストマネージャーとして使用した場合、as によってパス文字列が渡される
- with を抜けると、ディレクトリと、ディレクトリ内のすべてのファイルが削除される
- コンテキストマネージャーとして使用しなかった場合、オブジェクトの `cleanup()` を呼ぶことで同様の削除動作
- shutil
- `copyfile()`(宛先はファイルのみ) `copy()`(宛先ディレクトリ可) `copy2()`(宛先ディレクトリ可) `copymode()` `copystat()`
- ディレクトリ再帰操作 `rmtree()` `move()`
- shutil はコピー、移動での上書きでエラーは発生しない
- shutil は src, dst が同じだとエラー発生
- csv
- `reader(csvfile, dialect, **fmtparams)` `writer(csvfile, dialect, **fmtparams)`
- `writer.writerow()` `writer.writerows()`
- `DictReader(f, fieldnames, restkey, restval, dialect, *args, **kwds)`
- `DictWriter(f, fieldnames, restkey, extrasaction, dialect, *args, **kwds)`
- `Sniff()`
- `sniff(sample, delimiters=None)`
- `has_header(sample)`
- json
- `dumps(obj)` `loads(str)` オブジェクト ↔ 文字列
- `dump(obj, fp)` `load(fp)` オブジェクト ↔ ファイル(内文字列)
- urllib.parse
- `urlparse(urlstring)` url 文字列をパースして urllib.parse.ParseResult を返す
- `urllib.parse.ParseResult` の属性 (一部インデックスアクセスも可能)
- `scheme` `[0]`
- `netloc` `[1]`
- `path` `[2]`
- `params` `[3]`
- `query` `[4]`
- `flagment` `[5]`
- `username`
- `password`
- `hostname`
- `port`
- `parse_qs(qs)` クエリ文字列をパースして辞書を返す
- `parse_qsl(qs)` クエリ文字列をパースして、ペアのリストを返す
- `urlencode(query)` マッピングオブジェクトか、ペアのリストを渡すとクエリ文字列を返す
- `quote(string)` url として使用できる文字列へ変換 (パーセントエンコード)
- 空白文字は `%20` へエンコード
- デフォルトでは `/` はエンコードされない
- `quote_plus(string)` (同上)
- 空白文字は `+` へエンコード
- デフォルトでは `/` がエンコードされる
- `urljoin(base, url)`
- urllib.request
- `urlopen(url, data=None)`
- GET: url を文字列で指定、data は None
- POST: url を文字列で指定、data に bytes または ファイルオブジェクトを渡す
- 他の HTTP メソッドは、url に次の `Request` オブジェクトを渡す
- 戻り値は `http.client.HTTPResponse` (HTTP, HTTPS)
- (HTTP, HTTPS 以外だと `urllib.response.addinfourl` らしい)
- ファイルダウンロードの場合は `urlopen(~).read()`
- class `Request(url, data=None, 略, method=None)`
- base64
- `b64encode(s, altchars=None)` s に変換対象の **バイト列** を指定
- altchar には `+` `/` を置換する2バイト列を指定
- 戻り値もバイト列 (bytes)
- `urlsafe_b64encode()` では、url として使用できる様に変換する
- 具体的には `+` → `-`, `/` → `_` の変換が適用される
- `b64decode(s, altchars=None, validate=False)`
- `urlsafe_b64decode()`
- doctest
- `testmod()` モジュール中のドキュメントテストを実施する
- `testfile(filename)` テキストに記載されたドキュメントテストを実施する
- コマンドラインでの実行 `python -m doctest ファイル名`
- ファイル名が `.py` で終わる場合、そのファイルを単独モジュールとして読み込んで `testmod()` が実行される
- ファイル名が `.py` で終わらない場合、そのファイルを対象に `testfile()` が実行される
- unittest
- class `TestCase()` を継承してテストクラスを定義
- `test` で始まるメソッド名がテスト内容となる
- アサーションメソッド (assert*) を使用してテストを行う
- 通常は単一メソッド内のアサートは最初の失敗で停止だが、 `subTest(msg, **params)` で、失敗時も続行するテストが書ける
- 準備メソッド `setUp()` `setUpClass()`
- 事後メソッド `tearDown()` `tearDownClass()`
- コマンドラインインターフェース
- 基本 `python -m unittest 対象`
- 対象はモジュール、クラス、メソッドを指定可能
- `-b` 出力をバッファし、成功時は出力をしない
- `-c` Ctrl-C をテスト終了まで遅延させる (2回目の入力は通常通り割り込み)
- `-f` 初回のエラーでテストを停止
- `-k` テスト対象の部分文字列マッチング指定
- テストディスカバリ `python -m unittest discover ...`
- テストファイルの範囲を指定して実行
- `-v` 詳細出力
- `-s` ディスカバリ開始ディレクトリ
- `-p` テストファイル名パターン (デフォルト `test*.py`)
- `-t` 最上位のディスカバリディレクトリ
- unittest.mock
- class `Mock`
- spec, spec_set で指定しない限りは、キーワード引数で追加指定した属性以外を参照してもエラーにはならない
- spec, spec_set で指定した場合は、指定外の属性は AttributeError
- pdb, breakpoint()
- 処理中に `pdb.set_trace()` を挿入しておくと、実行中にその場所でデバッガ pdb が起動する
- `pdb.set_trace()` の代わりに組み込み関数 `breakpoint()` でも同じ
- 実際には `breakpoint()` によって `sys.breakpointhook` に設定されたオブジェクトが呼ばれる (デフォルトで sys.breakpointhook には pdb.set_trace が設定されている)
- 対話モードでは `pdb.run(デバッグ対象)` でデバッグ開始 (breakpoint() で開始する)
- コマンドラインから `python -m pdb ~.py` で実行すると、異常終了時にデバッグモードへ移行する
- 対話モードでは `pdb.pm()` で、異常終了時のデバッグが可能
- timeit
- コマンドラインインターフェース `python -m timeit`
- `-n` `-r` `-s` `-u` `-p` `-v`
- 回数、ループを行い、回数毎の時間が最短のものを、回数で割った値を表示する
- (100万回x5 で結果が 1s, 2s, 4s, 2s, 3s なら、 1s/1000000 = 1usec)
- python インターフェース
- 関数 `timeit()` `repeat()`
- class `Timer`
- メソッド `timeit()` `repeat()`