Python 3 エンジニア認定基礎試験 想定問題集
モジュールと入出力の要点整理と想定問題
公式の出題範囲の「6章 モジュール/7章 入出力」にあたる分野です。まず要点整理で全体をつかみ、下の演習で 26 問を 1 問ずつ解けます。答えると A〜D すべての解説が出ます。
この分野の小項目
- 6章冒頭・6.1・6.1.1 モジュールと import・スクリプトとしての実行(4 問) モジュールは定義や文を書いた .py ファイルで、名前は __name__ で得られる。import 文、from ... import ...、as による別名、import * の動き(_ で始まる名前は除く)。モジュールの初期化コードは最初の import 時に 1 回だけ実行され、変更後は importlib.reload() で再読込。python ファイル名 で実行すると __name__ が "__main__" になり、if __name__ == "__main__": の部分だけが動く。
- 6.1.2・6.1.3 モジュール検索パスとコンパイル済みファイル(4 問) import はまず組み込みモジュールを探し、次に sys.path のディレクトリを探す。sys.path は入力スクリプトのあるディレクトリ、PYTHONPATH、インストール時の既定値で初期化され、プログラムから変更できる。読み込みを速くするため、コンパイル済みのモジュールが __pycache__ ディレクトリに module.バージョン名.pyc としてキャッシュされる。
- 6.2・6.3 標準モジュールと dir() 関数(3 問) Python には標準モジュールのライブラリが付属する。sys は全てのインタープリタに組み込まれ、sys.ps1・sys.ps2 はプロンプトの文字列(対話モードのときだけ定義)。dir() はモジュールが定義する名前の一覧を並べ替えて返し、引数なしでは現在定義している名前を返す。組み込みの名前は builtins モジュールにある。
- 6.4・6.4.1〜6.4.3 パッケージ(__init__.py・__all__・相対インポート)(4 問) パッケージはドット付きモジュール名でモジュールを構造化する仕組みで、ディレクトリをパッケージとして扱わせるには __init__.py が必要(空でもよい)。from package import * で読み込むモジュールは __init__.py の __all__ で指定する。パッケージ内では from . import echo のような相対インポートが使え、メインモジュールとして使うモジュールでは絶対インポートを使う。第4版 6.4.3「複数のディレクトリにまたがるパッケージ」は現行の Web 版チュートリアルには該当節が無い。
- 7.1・7.1.1〜7.1.4 出力のフォーマット(f-string・format()・手作業・%)(5 問) str() は人が読みやすい表現、repr() はインタープリタが読める表現を返す。f-string(f や F を前に付けた文字列リテラル)では {式} を埋め込み、: の後に書式指定(例: {x:.3f}・{name:10})、!r などの変換、= 指定子も使える。str.format() は位置やキーワードで値を差し込む。str.rjust()・ljust()・center()・zfill() で手作業の整形、% 演算子による古い書式もある。
- 7.2・7.2.1・7.2.2 ファイルの読み書きと json(6 問) open(filename, mode, encoding=None) はファイルオブジェクトを返す。mode は 'r'(既定)・'w'・'a'・'r+'、'b' でバイナリモード。with 文を使うと例外が起きても確実に閉じられる。read()・readline()・ファイルの行の反復・write()(書いた文字数を返す)・tell()・seek()。json.dumps() で JSON 文字列に、json.dump() でファイルに書き出す(シリアライズ)。json.load() でファイルから読み戻す(デシリアライズ)。JSON ファイルは UTF-8 でエンコードする。
要点整理
モジュールと import・スクリプトとしての実行
import の形と __name__:何が名前空間に入るかで覚える
モジュールは定義や文を書いた .py ファイルで、モジュール名はファイル名から .py を除いたものです。モジュールの中では、グローバル変数 __name__ でその名前を文字列として得られます。
import 文の形ごとに「どの名前が使えるようになるか」が問われます。import fibo で増えるのは fibo という名前だけで、関数は fibo.fib のように書いて使います。from fibo import fib なら fib が直接使えますが、fibo という名前は定義されません。
from fibo import * は、アンダースコア(_)で始まる名前以外をすべて取り込みます。知らない名前で既存の定義を上書きするおそれがあるため、チュートリアルは普段は使わないよう勧めています。対話モードで入力を減らす目的なら構わないとしています。
モジュールの本体(初期化の文)は、同じセッションで最初に import されたときに 1 回だけ実行されます。ファイルを直した後にもう一度 import しても読み直されないので、importlib.reload() を使うか、インタープリタを起動し直します。
python fibo.py 50 のようにスクリプトとして実行すると、__name__ に "__main__" が入ります。末尾に if __name__ == "__main__": を書くと、その中はスクリプトとして動かしたときだけ実行され、import されたときは実行されません。
| 書き方 | 使えるようになる名前 | 呼び出し方の例 |
|---|---|---|
| import fibo | fibo | fibo.fib(10) |
| import fibo as fib | fib(モジュールの別名) | fib.fib(10) |
| from fibo import fib | fib(fibo は無い) | fib(10) |
| from fibo import fib as fibonacci | fibonacci | fibonacci(10) |
| from fibo import * | _ で始まる名前以外のすべて | fib(10) |
出典: Python チュートリアル 6.1 モジュールについてもうすこし/Python チュートリアル 6.1.1 モジュールをスクリプトとして実行する
モジュール検索パスとコンパイル済みファイル
検索パスの順番と .pyc:速くなるのは読み込みだけ
import spam を実行すると、まず同じ名前の組み込みモジュールを探し、無ければ sys.path に並んだディレクトリから spam.py を探します。sys.path(モジュール検索パス)は次の 3 つで初期化されます。
1 つ目は入力したスクリプトのあるディレクトリ(ファイルを指定しないときはカレントディレクトリ)です。2 つ目は環境変数 PYTHONPATH、3 つ目はインストールで決まる既定の場所で、慣例として site-packages を含みます。シェルの PATH は使われません。
スクリプトのディレクトリは検索パスの先頭に入り、標準ライブラリより先に探されます。作業フォルダに random.py のような標準モジュールと同じ名前のファイルを置くと、標準モジュールが隠れてしまいます。プログラムから sys.path を書き換えることもできます。
読み込みを速くするため、コンパイル済みのモジュールは __pycache__ ディレクトリに module.バージョン名.pyc の名前で保存されます。CPython 3.9 の spam.py なら spam.cpython-39.pyc です。ソースの更新日時と比べて、古ければ自動で作り直されます。
.pyc で速くなるのは読み込みの時間だけで、実行の速さは .py と変わりません。コマンドラインから直接実行したスクリプトは毎回コンパイルされ、結果は保存されません。コンパイル済みのモジュールはプラットフォームに依存しないので、異なる環境の間で共有できます。
| sys.path の初期化元 | 中身 | 注意点 |
|---|---|---|
| スクリプトのディレクトリ | 実行したファイルの場所(無ければカレント) | 先頭に入り、標準モジュールを隠すことがある |
| PYTHONPATH | 環境変数で足したディレクトリ | PATH と同じ書き方で並べる |
| インストール時の既定値 | 標準ライブラリや site-packages | インストール方法で決まる |
出典: Python チュートリアル 6.1.2 モジュール検索パス/Python チュートリアル 6.1.3 「コンパイル」された Python ファイル
標準モジュールと dir() 関数
標準モジュールと dir():組み込みの名前は builtins で見る
Python には標準ライブラリとして多くのモジュールが付いてきます。一部はインタープリタに組み込まれていて、どれが組み込まれるかは設定やプラットフォームで変わります。sys モジュールはすべてのインタープリタに組み込まれています。
sys.ps1 と sys.ps2 は、対話モードの一次プロンプト('>>> ')と二次プロンプト('... ')の文字列です。代入すればプロンプトを変えられます。この 2 つは対話モードのときだけ定義されるので、スクリプトで参照すると AttributeError になります。
dir() は、モジュールが定義している名前を並べ替えたリストで返します。引数なしで呼ぶと、変数・モジュール・関数など、今定義している名前を返します。
dir() の結果には len や print などの組み込みの名前は出てきません。組み込みの関数と変数の一覧を見たいときは、import builtins の後に dir(builtins) を実行します。
パッケージ(__init__.py・__all__・相対インポート)
パッケージ:__init__.py と __all__、相対インポートのドット
パッケージは、sound.effects.echo のようなドット付きの名前でモジュールを階層にまとめる仕組みです。通常のパッケージでは、各ディレクトリに __init__.py を置きます。中身は空でもよく、初期化のコードや __all__ を書くこともできます。
import a.b.c の形では、最後の要素以外はパッケージでなければなりません。最後の要素はモジュールかパッケージで、関数やクラスは指定できません。関数を直接使いたいときは from sound.effects.echo import echofilter と書きます。
from sound.effects import * の動きは __all__ の有無で変わります。__init__.py に __all__ があれば、そこに並べた名前のサブモジュールを読み込みます。無ければサブモジュールは読み込まず、__init__.py で定義された名前と、それまでに読み込まれたサブモジュールだけが入ります。
パッケージの中では相対インポートも使えます。ドット 1 つは今いるパッケージ、ドット 2 つは親のパッケージです。相対インポートは今のモジュールの名前をもとに解決されるため、アプリのメインとして動かすモジュールでは絶対インポートを使います。
| sound/filters/vocoder.py での書き方 | 読み込むもの |
|---|---|
| from . import equalizer | 同じ filters の equalizer |
| from .. import formats | 親 sound の formats |
| from ..effects import echo | 兄弟 effects の echo |
| from sound.effects import echo | 同じもの(絶対インポート) |
出典: Python チュートリアル 6.4 パッケージ/Python チュートリアル 6.4.1 パッケージから * を import する/Python チュートリアル 6.4.2 パッケージ内参照
出力のフォーマット(f-string・format()・手作業・%)
出力の整形:4 つの方法と、切り詰めない rjust()
値を見やすく出す方法は、f-string、str.format()、文字列メソッドによる手作業、% 演算子の古い文字列書式設定の 4 つです。
str() は人が読みやすい表現を、repr() はインタープリタが読める表現を返します。数値やリスト・辞書では同じになりますが、文字列では違います。str('Hi') は Hi、repr('Hi') は 'Hi' と引用符が付きます。
f-string では {式} の後に : と書式を書けます。f'{math.pi:.3f}' は 3.142 で、f の書式は切り捨てではなく丸めます。: の後に整数だけを書くと最小の幅になり、表の列をそろえられます。!r を付けると repr()、!s は str()、!a は ascii() を通してから整形します。
str.format() では {} に引数が入ります。{0}・{1} は引数の位置、{name} はキーワード引数です。'{1} and {0}'.format('spam', 'eggs') は eggs and spam になります。
rjust()・ljust()・center() は幅をそろえた新しい文字列を返すだけで、何も表示しません。幅より長い文字列は切り詰めずにそのまま返します。zfill() は左側を 0 で埋め、'-3.14'.zfill(7) は '-003.14' のように符号を先頭に残します。
| 式 | 結果 |
|---|---|
| f'{math.pi:.3f}' | '3.142' |
| '{1} and {0}'.format('spam', 'eggs') | 'eggs and spam' |
| '%5.3f' % math.pi | '3.142' |
| '12'.zfill(5) | '00012' |
| '-3.14'.zfill(7) | '-003.14' |
| 'Python'.rjust(3) | 'Python'(切り詰めない) |
| repr('Hi') | "'Hi'" |
出典: Python チュートリアル 7.1 出力を見やすくフォーマットする/Python チュートリアル 7.1.3 手作業での文字列フォーマット
ファイルの読み書きと json
ファイルと json:mode・終わりの合図・seek の制限
open() はファイルオブジェクトを返します。mode を省略すると 'r'(読み出し)です。'w' は同じ名前の既存ファイルの中身を消し、'a' は末尾に追記します。'b' を付けるとバイナリモードになり、データは bytes として扱われます。
テキストモードでは、読むときに環境ごとの改行が \n に変換され、書くときに戻されます。画像などのバイナリファイルが壊れるので、それらはバイナリモードで開きます。文字コードは encoding 引数で指定できます。省略したときの既定値は Python の版や環境で違うため、encoding='utf-8' のように明示すると確実です。
with 文で開くと、ブロックを抜けたときに例外があってもファイルが閉じられます。閉じた後は f.closed が True になり、読もうとすると ValueError です。
f.read() は全体を、f.read(size) は最大 size 文字(バイナリなら size バイト)を読みます。readline() は改行を残したまま 1 行を返し、空行は '\n'、末尾に達すると空文字列 '' を返します。for line in f: と書くと 1 行ずつ効率よく読めます。f.write() は書いた文字数を返し、文字列以外は先に変換が必要です。
seek() の whence は 0 が先頭、1 が現在位置、2 が末尾です。テキストモードで許されるのは先頭からの位置だけで、例外として seek(0, 2) で末尾へ移れます。有効な位置は tell() の戻り値か 0 だけです。
json モジュールは、リストや辞書を JSON の文字列にするシリアライズと、その逆のデシリアライズを行います。JSON ファイルは UTF-8 で書きます。pickle は複雑なオブジェクトも扱えますが Python 専用で、信頼できないデータを読み込むと任意のコードが動くおそれがあります。
| 関数 | 向き | 相手 |
|---|---|---|
| json.dumps() | データ → JSON | 文字列を返す |
| json.dump() | データ → JSON | ファイルに書く(dump(x, f)) |
| json.load() | JSON → データ | ファイルから読む(x = load(f)) |
出典: Python チュートリアル 7.2 ファイルを読み書きする/Python チュートリアル 7.2.1 ファイルオブジェクトのメソッド/Python チュートリアル 7.2.2 json による構造化されたデータの保存
演習(26 問)
結果はこのブラウザに保存され、ハブの「自分の成績」と弱点モードに使われます。
第 1 問 / 26 問
問題を読み込んでいます…
全問と解説の一覧
正解と解説は折りたたんであります。先に自分で考えてから開いてください。
全 26 問
モジュールと import・スクリプトとしての実行
共通処理を mylib.py にまとめ、末尾に次を書いた。 if __name__ == "__main__": main() 別のスクリプトで import mylib したとき、main() はどうなる?
A. import のたびに main() が呼ばれる B. 最初の import のときだけ main() が呼ばれる C. main() は呼ばれない D. if 文が原因で ImportError になる
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? import するたびに中の処理が動くという考えです。 import されたモジュールの __name__ はモジュール名('mylib')になるため、if の条件が成り立たず main() は呼ばれない。 【B(不正解)】 ? 初期化の処理が 1 回だけ動く点に注目した考えです。 モジュールの本体が実行されるのは最初の import の 1 回だけだが、そのときも __name__ は 'mylib' なので main() は呼ばれない。 【C(正解)】 ? import されたときの __name__ の値を考える選択肢です。 __name__ が "__main__" になるのは python mylib.py のようにスクリプトとして実行したときだけ。import では if の中は動かない。 【D(不正解)】 ? import そのものが失敗するという考えです。 このガードはチュートリアルでも紹介される普通の書き方で、ImportError の原因にはならない。
tools.py には def _helper(): と def run(): の 2 つだけがあり、__all__ は書いていない。from tools import * の後で使える名前はどれ?
A. run だけ B. _helper と run の両方 C. _helper だけ D. tools という名前だけ
この問題へのリンク答えと解説
正解: A 【A(正解)】 ? 名前の先頭の文字で取り込むかどうかが変わる、という考えです。 __all__ が無いとき、import * はアンダースコア(_)で始まる名前を除いて取り込む。そのため run だけが使える。 【B(不正解)】 ? 定義した名前をすべて取り込む、という考えです。 _ で始まる名前は import * では取り込まれない。_helper は tools._helper のように書かないと使えない。 【C(不正解)】 ? _ 付きの名前だけが公開される、という考えです。 実際は逆で、_ で始まる名前が import * の対象から外れる。 【D(不正解)】 ? import tools と同じ結果になる、という考えです。 from tools import * はモジュール名 tools を定義しない。中の名前を直接取り込む書き方である。
対話モードで import config した後、エディタで config.py の値を書き換えた。もう一度 import config しても新しい値にならない。インタープリタを終了せずに反映させる方法は?
A. del config としてから import config を 2 回続けて書く B. import config as config2 と別名で読み込む C. importlib.reload(config) で読み込み直す D. dir(config) を実行して名前の一覧を作り直す
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? 名前を消してから読み込み直す、という考えです。 名前を消しても、モジュールは同じセッションで 1 回しか読み込まれないため、ファイルは読み直されない。 【B(不正解)】 ? 別の名前で読み込めば新しく読まれる、という考えです。 as は名前を付け替えるだけで、すでに読み込んだモジュールを指すだけになる。 【C(正解)】 ? 読み込み済みのモジュールをもう一度読み込む関数を使う方法です。 モジュールは効率のため 1 セッションで 1 回だけ読み込まれる。修正を反映するには importlib.reload() を使うか、インタープリタを再起動する。 【D(不正解)】 ? 名前の一覧を表示する関数を使う方法です。 dir() は定義されている名前を返すだけで、ファイルを読み直す働きはない。
コマンドラインで python fibo.py 50 と実行した。このとき fibo.py の中で __name__ に入っている値は?
A. "fibo" B. "__main__" C. "fibo.py" D. "50"
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? ファイル名から .py を除いた文字列です。 "fibo" になるのは import fibo で読み込まれたとき。スクリプトとして実行したときは別の値になる。 【B(正解)】 ? スクリプトとして動かしたときに使われる特別な名前です。 スクリプトとして実行すると __name__ に "__main__" が設定される。__main__ の判定はこれを利用している。 【C(不正解)】 ? 拡張子まで含めたファイル名です。 __name__ はモジュール名を表し、拡張子付きのファイル名が入ることはない。 【D(不正解)】 ? コマンドラインで渡した引数です。 引数は sys.argv に入る。__name__ とは関係がない。
モジュール検索パスとコンパイル済みファイル
作業フォルダに自作の random.py を置き、同じフォルダの main.py で import random した。すると標準の random.randint() が使えなくなった。原因として最も適切なものは?
A. random は組み込みモジュールなので、自作ファイルとは衝突しない B. スクリプトのあるフォルダが検索パスの先頭にあり、標準ライブラリより先に見つかった C. PYTHONPATH を設定していないと標準ライブラリが読み込まれない D. __pycache__ に古いキャッシュが残っていたため
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? インタープリタに組み込まれたモジュールが最初に探される点に注目した考えです。 random は組み込みモジュールではなく、モジュール検索パス上のファイルとして探される。そのため同名のファイルの影響を受ける。 【B(正解)】 ? sys.path の並び順に注目した考えです。 スクリプトのディレクトリは sys.path の先頭に入り、標準ライブラリより先に探される。同名のファイルが標準モジュールを隠してしまう。 【C(不正解)】 ? 環境変数の設定が必要だという考えです。 PYTHONPATH は追加の検索場所を足すもので、未設定でも標準ライブラリはインストール時の既定の場所から読み込める。 【D(不正解)】 ? コンパイル済みファイルのキャッシュに注目した考えです。 キャッシュはソースの更新日時と比べて自動で作り直される。どのファイルが選ばれるかは検索パスの順番で決まる。
モジュール検索パス(sys.path)の初期化に使われないものはどれ?
A. 入力されたスクリプトのあるディレクトリ B. 環境変数 PYTHONPATH に書いたディレクトリ C. インストール方法で決まる既定の場所(site-packages など) D. 環境変数 PATH に書いたディレクトリ
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? 実行したファイルが置かれている場所です。 チュートリアルが挙げる初期化元の 1 つ目。ファイルを指定しないときはカレントディレクトリになる。 【B(不正解)】 ? シェルの PATH と同じ書き方で指定する環境変数です。 PYTHONPATH は sys.path の初期化元の 1 つとしてチュートリアルに載っている。 【C(不正解)】 ? Python を入れたときに決まる場所です。 インストールに依存した既定値も初期化元の 1 つで、慣例として site-packages を含む。 【D(正解)】 ? コマンドの実行ファイルを探すための環境変数です。 PATH はシェルがコマンドを探す場所で、sys.path の初期化元には含まれない。
CPython 3.9 で spam.py を import した。読み込みを速くするために作られるキャッシュのファイルはどれ?
A. spam.py と同じ場所の spam.pyc B. __pycache__/spam.cpython-39.pyc C. __pycache__/spam.py.bak D. site-packages/spam.cpython-39.pyc
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? ソースのすぐ隣に置く形です。 ソースがある通常の import では、キャッシュは __pycache__ の中に作られる。 【B(正解)】 ? 専用のディレクトリに、版の名前を付けて置く形です。 コンパイル済みモジュールは __pycache__ に module.バージョン名.pyc の名前で置かれる。3.9 なら cpython-39 が付く。 【C(不正解)】 ? 元のソースの控えを作る形です。 作られるのはコンパイル済みの .pyc で、ソースの控えではない。 【D(不正解)】 ? パッケージのインストール先に置く形です。 キャッシュはモジュールのある場所の __pycache__ に作られ、site-packages にまとめて置かれるわけではない。
チームで「.pyc を使えばプログラムが速くなるのか」が話題になった。コンパイル済みファイル(.pyc)の説明として最も適切なものは?
A. 実行そのものが速くなり、ループの処理時間も短くなる B. コマンドラインで直接実行したスクリプトも毎回キャッシュされる C. 速くなるのは読み込みの時間だけで、実行速度は .py と同じ D. プラットフォームごとに中身が違うので、OS をまたいで共有できない
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? 計算の速さが上がるという考えです。 .pyc でも実行速度は .py と変わらない。速くなるのは読み込みの時間だけである。 【B(不正解)】 ? python ファイル名 で動かしたときの扱いです。 コマンドラインから直接読み込んだモジュールは毎回コンパイルされ、結果は保存されない。 【C(正解)】 ? どの段階の時間が短くなるかを限定した考えです。 チュートリアルは、.pyc で速くなるのは読み込みにかかる時間だけだと説明している。 【D(不正解)】 ? Windows と Linux などの間で使い回せるかという話です。 コンパイル済みモジュールはプラットフォームに依存しないため、異なる環境の間で共有できる。
標準モジュールと dir() 関数
対話モードで変数をいくつか作った後、引数なしで dir() を呼んだ。返ってくるものは?
A. 現在定義されている名前を並べ替えたリスト B. インストール済みのパッケージの一覧 C. len や print などの組み込み関数を含む全名前 D. カレントディレクトリのファイル名の一覧
この問題へのリンク答えと解説
正解: A 【A(正解)】 ? 今の名前空間にある名前を確かめる使い方です。 引数なしの dir() は、変数・モジュール・関数など現在定義している名前を並べ替えて返す。 【B(不正解)】 ? 環境に入っているパッケージを調べる使い方です。 インストール済みパッケージの一覧は pip list で確かめる。dir() の役割ではない。 【C(不正解)】 ? 組み込みの名前まで含めた一覧という考えです。 dir() は組み込みの関数や変数を列挙しない。それらは builtins モジュールで調べる。 【D(不正解)】 ? フォルダの中身を表示する使い方です。 ファイルの一覧を返すのは os モジュールの関数などで、dir() は名前空間の名前を返す。
dir() の結果に len や print が出てこない。組み込みの関数や変数の名前の一覧を確かめる方法として適切なものは?
A. import sys の後に dir(sys) を実行して確かめる B. dir() に引数 True を渡して表示の範囲を広げる C. builtins を import して dir(builtins) を見る D. help() を引数なしで実行して一覧を探す
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? インタープリタに関する情報をまとめたモジュールを調べる方法です。 dir() に sys を渡すと sys モジュールの名前が並ぶだけで、組み込み関数の一覧にはならない。 【B(不正解)】 ? 引数で表示の範囲を広げる方法です。 dir() には組み込みの名前を含めるための引数は無い。 【C(正解)】 ? 組み込みの名前が定義されている標準モジュールを調べる方法です。 組み込みの関数と変数は builtins モジュールで定義されているので、dir(builtins) で一覧できる。 【D(不正解)】 ? 対話的なヘルプを起動する方法です。 help() は説明を読むための機能で、チュートリアルが組み込み名の一覧として示す方法は dir(builtins) である。
対話モードで sys.ps1 を表示できたので、同じ処理をスクリプトに書いた。 import sys print(sys.ps1) python ファイル名 で実行するとどうなる?
A. 対話モードと同じ '>>> ' が表示される B. 空の文字列が表示される C. None が表示される D. AttributeError になる
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? 対話モードの既定のプロンプトの文字列です。 sys.ps1 は対話モードのときだけ定義される。スクリプトとして実行した場合は存在しない。 【B(不正解)】 ? 値が空のまま用意されているという考えです。 空文字列が用意されるわけではなく、属性そのものが定義されていない。 【C(不正解)】 ? 値が無いことを表す特別なオブジェクトです。 None が入っているのではなく、属性が無いのでエラーになる。 【D(正解)】 ? オブジェクトに無い属性を参照したときの例外です。 sys.ps1 と sys.ps2 は対話モードのときだけ定義されるため、スクリプトでは属性が無く AttributeError が送出される。
パッケージ(__init__.py・__all__・相対インポート)
自作のモジュールを sound というディレクトリにまとめ、import sound.effects.echo のように使いたい。各ディレクトリに置くべきファイルは?
A. __init__.py B. __main__.txt C. requirements.txt D. setup.cfg
この問題へのリンク答えと解説
正解: A 【A(正解)】 ? ディレクトリを読み込むときに最初に実行されるファイルです。 通常のパッケージでは、ディレクトリをパッケージとして扱わせるために __init__.py が必要。中身は空でもよい。 【B(不正解)】 ? メインの処理を書いておくテキストファイルです。 テキストファイルを置いてもパッケージにはならない。パッケージには __init__.py を置く。 【C(不正解)】 ? 必要なパッケージとバージョンを並べるファイルです。 requirements.txt は pip でまとめてインストールするためのもので、パッケージの構造とは関係がない。 【D(不正解)】 ? 配布の設定を書くファイルです。 チュートリアルの説明では、パッケージとして扱わせるのに必要なのは __init__.py である。
sound/effects/__init__.py に __all__ = ["echo", "surround"] と書いた。from sound.effects import * を実行すると何が読み込まれる?
A. effects フォルダにある全サブモジュール B. __init__.py に書いた関数だけで、サブモジュールは読み込まれない C. echo と surround のサブモジュール D. 何も読み込まれず ImportError になる
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? ファイルをすべて探して読み込むという考えです。 Python はフォルダ内のファイルを全部探すことはしない。__all__ があればそこに書いた名前だけを読み込む。 【B(不正解)】 ? __init__.py で定義した名前だけが入る、という考えです。 __all__ が無いときはサブモジュールを読み込まない。この問題では __all__ があるので、リストの名前が読み込まれる。 【C(正解)】 ? __all__ に並べた名前をもとにした考えです。 from パッケージ import * では、__init__.py の __all__ に書いた名前のサブモジュールが読み込まれる。 【D(不正解)】 ? import * がパッケージでは使えないという考えです。 パッケージにも import * は使える。製品のコードでは勧められないが、エラーにはならない。
sound/filters/vocoder.py から、兄弟のサブパッケージにある sound/effects/echo.py を相対インポートで読み込みたい。正しい書き方は?
A. from . import echo B. from ..effects import echo C. from .effects import echo D. import ..effects.echo
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? 今いるパッケージ(filters)を起点にする書き方です。 ドット 1 つは今いるパッケージ filters を指す。echo は filters の中には無い。 【B(正解)】 ? 親のパッケージに上がってから下る書き方です。 ドット 2 つで親の sound を指し、そこから effects の echo を読み込める。 【C(不正解)】 ? 今いるパッケージの中にある effects を指す書き方です。 これは sound/filters/effects を探すことになり、目的の sound/effects には届かない。 【D(不正解)】 ? import 文に直接ドットを付ける書き方です。 相対インポートは from ... import の形で書く。import の後に先頭のドットは書けない。
sound/effects/echo.py には関数 echofilter がある。次のうち、エラーになる書き方はどれ?
A. import sound.effects.echo B. from sound.effects import echo C. from sound.effects.echo import echofilter D. import sound.effects.echo.echofilter
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? サブモジュールまでをドットでつないで読み込む書き方です。 最後の要素 echo はモジュールなので問題ない。使うときは sound.effects.echo.echofilter と書く。 【B(不正解)】 ? パッケージからサブモジュールを取り出す書き方です。 from パッケージ import サブモジュール の形で、echo.echofilter と短く書けるようになる。 【C(不正解)】 ? モジュールから関数を直接取り出す書き方です。 from の後に書いたモジュールから関数を取り込める。echofilter() と直接呼べる。 【D(正解)】 ? 関数名までをドットでつないで import する書き方です。 import a.b.c の形では、最後の要素はモジュールかパッケージでなければならず、関数やクラスは指定できない。
出力のフォーマット(f-string・format()・手作業・%)
import math の後に print(f'{math.pi:.3f}') を実行した。表示されるものは?
A. 3.14 B. 3.141 C. 3.1416 D. 3.142
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? 小数点以下 2 桁の表示です。 .3f は小数点以下 3 桁の指定なので、2 桁にはならない。 【B(不正解)】 ? 小数点以下 3 桁で切り捨てた表示です。 書式指定 f は切り捨てではなく丸めるので、4 桁目の 5 が繰り上がる。 【C(不正解)】 ? 小数点以下 4 桁の表示です。 .3f は小数点以下 3 桁の指定なので、4 桁にはならない。 【D(正解)】 ? 小数点以下 3 桁に丸めた表示です。 f-string では : の後に書式を書ける。.3f は小数点以下 3 桁で、π は 3.142 と表示される。
print('{1} and {0}'.format('spam', 'eggs')) を実行した。表示されるものは?
A. spam and eggs B. eggs and spam C. 1 and 0 D. IndexError になる
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? 引数を渡した順に並べた結果です。 {} の中の数字は引数の位置を表す。{1} が先に来るので、渡した順のままにはならない。 【B(正解)】 ? {} の中の数字を引数の位置として読んだ結果です。 str.format() では {0} が 1 番目、{1} が 2 番目の引数を表す。{1} が 'eggs' なので eggs and spam になる。 【C(不正解)】 ? {} の中の数字がそのまま出る、という考えです。 {1} はそのまま表示されず、対応する引数の値に置き換わる。 【D(不正解)】 ? 番号の指定が範囲外だという考えです。 引数は 2 つあり、番号 0 と 1 はどちらも範囲内なのでエラーにならない。
数値の文字列を 0 埋めして幅をそろえたい。'-3.14'.zfill(7) の結果は?
A. '-003.14' B. '00-3.14' C. '-3.1400' D. '-3.14'
この問題へのリンク答えと解説
正解: A 【A(正解)】 ? 符号の後ろに 0 を足した結果です。 zfill() は符号を考えて、符号の後ろに 0 を詰める。全体が 7 文字になるよう 0 が 2 つ入る。 【B(不正解)】 ? 文字列の左端にそのまま 0 を足した結果です。 zfill() は符号を正しく扱うので、符号より前に 0 を置くことはない。 【C(不正解)】 ? 右側に 0 を足した結果です。 zfill() は数値文字列の左側に 0 を詰めるメソッドで、右側には足さない。 【D(不正解)】 ? 何も変わらない、という結果です。 元の文字列は 5 文字で幅 7 より短いので、0 が足される。
表の列幅を 3 文字にそろえるつもりで 'Python'.rjust(3) と書いた。結果は?
A. 'Pyt' B. 'hon' C. 'Python' D. ValueError になる
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? 先頭から 3 文字で切った結果です。 rjust() は文字列を切り詰めない。切りたいときは x.ljust(n)[:n] のようにスライスを足す。 【B(不正解)】 ? 右寄せなので末尾 3 文字が残る、という結果です。 右寄せでも文字を削ることはしない。幅より長い文字列はそのまま返る。 【C(正解)】 ? 元の文字列のままという結果です。 rjust() は入力が指定の幅より長いとき、切り詰めずにそのまま返す。 【D(不正解)】 ? 幅が足りないことをエラーで知らせる、という考えです。 幅が短くてもエラーにはならず、元の文字列が返る。
print(str('Hi'), repr('Hi')) を実行した。表示されるものは?
A. Hi Hi B. 'Hi' 'Hi' C. 'Hi' Hi D. Hi 'Hi'
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? 2 つの関数が同じ表現を返す、という結果です。 数値やリストでは同じ表現になるが、文字列では repr() の結果に引用符が付く。 【B(不正解)】 ? どちらにも引用符が付く、という結果です。 str() は人が読みやすい表現を返すので、引用符は付かない。 【C(不正解)】 ? str() の方に引用符が付く、という結果です。 引用符が付くのはインタープリタが読める表現を返す repr() の方である。 【D(正解)】 ? repr() の方に引用符が付く、という結果です。 str() は人が読みやすい表現、repr() はインタープリタが読める表現を返す。文字列の repr() には引用符が付く。
ファイルの読み書きと json
毎日の作業記録を log.txt の末尾に書き足したい。今までの内容は消したくない。open() の mode に指定するものは?
A. 'r' B. 'w' C. 'a' D. 'b'
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? mode を省略したときと同じ指定です。 'r' は読み出し専用なので、書き込みはできない。 【B(不正解)】 ? 書き込み専用で開く指定です。 'w' は同じ名前の既存ファイルの内容を消してしまうので、今までの記録が失われる。 【C(正解)】 ? 追記用に開く指定です。 'a' で開くと、書き込んだ内容は自動的にファイルの末尾に追加される。 【D(不正解)】 ? ほかのモードに付け足して使う指定です。 'b' はバイナリモードにする指定で、単独では書き足しの意味にならない。
次のコードの最後の行を実行するとどうなる? with open('memo.txt', encoding='utf-8') as f: head = f.readline() rest = f.read()
A. 2 行目以降の内容が rest に入る B. ValueError になる C. 空の文字列が rest に入る D. ファイルが自動で開き直され、先頭から全部が入る
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? ファイルが開いたまま続きを読める、という考えです。 with 文を抜けた時点でファイルは閉じられているので、続きは読めない。 【B(正解)】 ? 閉じたファイルに入出力をしたときの例外です。 with ブロックの後は f.closed が True。閉じたファイルを読もうとすると ValueError(I/O operation on closed file.)になる。 【C(不正解)】 ? ファイルの終わりに達したときと同じ結果になる、という考えです。 空文字列が返るのは開いたファイルで末尾に達したとき。閉じたファイルではエラーになる。 【D(不正解)】 ? 必要なときに自動で開き直される、という考えです。 閉じたファイルオブジェクトが自動で開き直されることはない。
readline() を繰り返し呼んでファイルを 1 行ずつ読む。途中に空行があるファイルで、末尾に達したと判断できる戻り値は?
A. '\n' B. None C. -1 D. ''(空の文字列)
この問題へのリンク答えと解説
正解: D 【A(不正解)】 ? 改行文字だけの文字列です。 '\n' は空行を読んだときの戻り値で、ファイルの途中でも返る。 【B(不正解)】 ? 値が無いことを表す特別なオブジェクトです。 readline() は末尾で None を返さない。文字列で終わりを知らせる。 【C(不正解)】 ? ほかの言語でよく使われる終わりの合図です。 テキストモードの readline() は常に文字列を返し、数値は返さない。 【D(正解)】 ? 1 文字も含まない文字列です。 readline() が空文字列を返したら末尾に達した印。空行は '\n' なので区別できる。
テキストモードで開いたログファイルの末尾へ移動して、続きを書き足したい。チュートリアルの説明で許されている呼び出しは?
A. f.seek(-10, 2) B. f.seek(0, 2) C. f.seek(3, 1) D. f.seek(25)
この問題へのリンク答えと解説
正解: B 【A(不正解)】 ? 末尾から 10 戻った位置へ移る呼び出しです。 末尾を基準にした負の移動はバイナリモードでの使い方。テキストモードで許されるのは先頭基準と seek(0, 2) だけ。 【B(正解)】 ? whence に 2 を指定し、移動量を 0 にする呼び出しです。 テキストファイルでは先頭からの位置だけが許されるが、例外として seek() の seek(0, 2) で末尾へ移動できる。 【C(不正解)】 ? 今の位置から 3 進む呼び出しです。 whence に 1(現在位置)を使う移動は、チュートリアルではバイナリモードでの使い方として説明されている。 【D(不正解)】 ? 先頭から 25 の位置へ移る呼び出しです。 テキストモードで有効な位置は tell() が返した値か 0 だけ。任意の数値を使うと動きは保証されない。
アプリの設定を辞書 conf にまとめ、書き込み用に開いたファイル f へ JSON 形式で保存したい。適切な書き方は?
A. json.dump(conf, f) B. json.dumps(conf, f) C. json.load(conf, f) D. f.write(conf)
この問題へのリンク答えと解説
正解: A 【A(正解)】 ? データとファイルの両方を渡す関数です。 json.dump() は Python のデータをシリアライズし、ファイルオブジェクトへ直接書き出す。 【B(不正解)】 ? データを JSON の文字列に変える関数です。 json.dumps() は文字列を返す関数で、2 番目の引数にファイルを受け取らない。 【C(不正解)】 ? ファイルから JSON を読み込む関数です。 json.load() はデシリアライズ(読み戻し)用で、保存には使わない。 【D(不正解)】 ? ファイルに直接書き込むメソッドです。 write() に渡せるのは文字列(テキストモード)だけ。辞書をそのまま渡すと TypeError になる。
出典: Python チュートリアル 7.2.2 json による構造化されたデータの保存/json --- JSON エンコーダおよびデコーダ
Python で集計したデータを、別の言語で書かれた社内システムにファイルで渡したい。受け取ったデータを安全に読み込める形も望ましい。適切な方法は?
A. pickle で保存して渡す B. str() で文字列にして渡す C. json で保存して渡す D. __pycache__ の .pyc を渡す
この問題へのリンク答えと解説
正解: C 【A(不正解)】 ? 複雑な Python オブジェクトもそのまま保存できる方式です。 pickle は Python 専用の形式で、他の言語のアプリとの通信には使えない。信頼できないデータの読み込みも危険である。 【B(不正解)】 ? 人が読みやすい表現に変える方法です。 str() の結果は Python の表現なので、相手側で入れ子のリストや辞書を解析するのが難しい。 【C(正解)】 ? 広く使われるデータ交換形式で保存する方法です。 JSON は多くの言語で使えるデータ交換形式で、json モジュールで保存と読み戻しができる。 【D(不正解)】 ? コンパイル済みファイルを渡す方法です。 .pyc はモジュールの読み込みを速くするキャッシュで、データ交換の形式ではない。
この分野に出てくる用語(42 語)
__all__:from パッケージ import * で読み込むモジュール名を並べたリスト。__init__.py に書く。
__init__.py:ディレクトリをパッケージとして扱わせるためのファイル。空でもよく、初期化コードや __all__ を書ける。
__main__:スクリプトとして直接実行したときの __name__ の値。if __name__ == "__main__": の中は import されたときには実行されない。
__name__:モジュールの名前が入るグローバル変数。スクリプトとして実行したモジュールでは "__main__" になる。
__pycache__:コンパイル済みのモジュールを module.バージョン名.pyc としてキャッシュするディレクトリ。読み込みを速くするためのもの。
builtins:len() や print() などの組み込みの関数・変数が定義されているモジュール。dir(builtins) で一覧できる。
dir():モジュールなどが定義している名前の一覧を、並べ替えたリストで返す組み込み関数。引数なしでは今定義している名前を返す。
f-string:先頭に f か F を付けた文字列リテラル。{式} の部分に式の値を埋め込める。
import 文:モジュールを読み込む文。from モジュール import 名前 や、as で別名を付ける書き方もある。
ImportError:import 文でモジュールの読み込みに失敗したときや、from ... import で名前が見つからないときに送出される例外。
importlib.reload():読み込み済みのモジュールをもう一度読み込む関数。モジュールは 1 セッションで 1 回しか読み込まれないため、修正を反映するときに使う。
json:リストや辞書などのデータを JSON 形式の文字列に変換したり戻したりする標準モジュール。
json.dump():Python のデータを JSON 形式にして、ファイルオブジェクトに直接書き出す関数。json.dump(x, f) と書く。
json.dumps():Python のデータを JSON 形式の文字列にして返す関数。json.dumps([1, 'simple']) は '[1, "simple"]' になる。
json.load():読み込み用に開いたファイルから JSON を読み、Python のデータに戻す関数。x = json.load(f) と書く。
open():ファイルを開いてファイルオブジェクトを返す組み込み関数。mode は 'r'(既定)・'w'・'a'・'r+' などで、'b' を付けるとバイナリモード。
os:オペレーティングシステムと対話する関数を提供する標準モジュール。import os の形で使う。
pickle:複雑な Python オブジェクトを保存できる形に変える標準モジュール。Python 専用で、信頼できないデータを読み込むのは危険。
readline():ファイルから 1 行を読むメソッド。行末の改行は残り、末尾に達すると空文字列を返す。空行は '\n' になる。
repr():インタープリタが読める形の文字列表現を返す組み込み関数。str() は人が読みやすい表現を返す。
requirements.txt:必要なパッケージとバージョンを並べたファイル。pip freeze の出力を保存し、pip install -r でまとめて入れる。
rjust():文字列を指定の幅で右寄せにした新しい文字列を返すメソッド。幅より長い文字列は切り詰めずにそのまま返す。
seek():ファイルの読み書きの位置を移すメソッド。f.seek(offset, whence) の whence は 0 が先頭、1 が現在位置、2 が末尾を基準にする。
site-packages:追加でインストールしたパッケージが置かれるディレクトリ。モジュール検索パスの既定値に含まれる。
str.format():文字列の {} に位置やキーワードで値を差し込むメソッド。
str():オブジェクトを人が読みやすい形の文字列にする組み込みの型。文字列に使うと引用符の付かない表現になる。
sys.argv:スクリプト名とそれに続く引数を文字列のリストで持つ変数。スクリプト名も引数も無いと sys.argv[0] は空文字列になる。
sys.ps1:対話モードの一次プロンプト(既定は '>>> ')の文字列。sys.ps2 は二次プロンプト('... ')。どちらも対話モードのときだけ定義される。
tell():ファイルの今の位置を整数で返すメソッド。バイナリモードでは先頭からのバイト数、テキストモードでは意味の決まっていない値になる。
with 文:ブロックを抜けるときに後始末を自動で行う文。ファイルは途中で例外が起きても確実に閉じられる。
zfill():数値の文字列の左側を 0 で埋めて指定の幅にする文字列メソッド。符号は先頭に残る('-3.14'.zfill(7) は '-003.14')。
シリアライズ:データを保存や送信ができる文字列表現に変換すること。逆に文字列から元のデータを作り直すことをデシリアライズという。
テキストモード:ファイルを文字列として読み書きするモード。open() の mode に 'b' を付けないとこのモードになり、改行の変換も行われる。
バイナリモード:open() の mode に 'b' を付けて、データを bytes オブジェクトとして読み書きするモード。画像などのファイルに使う。
パッケージ:ドット付きのモジュール名でモジュールを階層的にまとめる仕組み。ディレクトリに __init__.py を置いて作る。
ファイルオブジェクト:open() が返すオブジェクト。read()・readline()・write() などのメソッドで読み書きする。
モジュール:定義や文を書いた .py ファイル。import で読み込んで、その中の関数や変数を使う。
モジュール検索パス:import がモジュールを探すディレクトリの一覧(sys.path)。組み込みモジュールの次に、ここに並んだ場所を探す。
古い文字列書式設定:'%5.3f' % 値 のように % 演算子で文字列を整形する従来の方法。
相対インポート:先頭のドットで現在や親のパッケージを表して import する書き方。メインモジュールでは使わず絶対インポートを使う。
対話モード:端末から入力を受け取り、入力した文をその場で実行するインタープリタの動作モード。
標準ライブラリ:Python に最初から付属するモジュールの集まり。追加のインストールなしで使える。
独学の次に、講座で体系立てて学びたい人へ
この問題集は独学用です。IT の基礎から講師つきで体系立てて学びたい人には、資格や IT の講座がそろうスクールも選択肢になります。
本ページは広告・アフィリエイトプログラムを利用しており、リンク経由でのお申し込み・購入により当サイトに収益が発生することがあります。ただし、ランキング・評価・掲載内容は広告費や報酬の有無に関わらず編集部の独自基準で決定しており、広告主からの指示により内容を変更することはありません。
IT・Webデザイン・資格まで幅広い講座。生成AI/DX講座はリスキリング補助金の対象
まずは無料ではじめられます。リンク先は公式サイトです。
このサービスの解説記事を読む →