Python3エンジニア認定基礎試験 第6章 モジュール 予想問題と解説
Python3エンジニア認定基礎試験「第6章 モジュール」の予想問題を15問収録しています。各問を解説つきで掲載し、全問は演習画面で解けます。出題は公式シラバスの範囲内です。
この章の要点
モジュールの取り込み、標準モジュールとdir、モジュールについてもうすこし、モジュールをスクリプトとして実行する、コンパイル済みPythonファイル、パッケージから*をimportするなどを扱う分野です。全15問(基礎4問・標準11問)を収録しています。
- モジュールの取り込み
- 標準モジュールとdir
- モジュールについてもうすこし
- モジュールをスクリプトとして実行する
- コンパイル済みPythonファイル
- パッケージから*をimportする
情報源と編集区分
公式範囲を確認し、問題数・難易度・確認点は当サイトが集計・編集。
試験概要(公式)確認しておきたいポイント
当サイトの作問時に観察した、取り違えやすい論点です(公式の統計ではありません)。
- import モジュール名 と from モジュール名 import 名前 の違い。前者は呼ぶときモジュール名を前に付ける必要がある。
- 語順の取り違え。from を先に書き、import を後に書く。
この章に関連する比較記事
混同しやすい2つの概念を並べて整理した記事です。
よくある質問
Q第6章 モジュールは何問収録されていますか?
現在15問を収録しています。内訳は基礎4問・標準11問です。
Q第6章 モジュールの頻出論点は何ですか?
モジュールの取り込み、標準モジュールとdir、モジュールについてもうすこし、モジュールをスクリプトとして実行する、コンパイル済みPythonファイル、パッケージから*をimportするなどが出題対象です(当サイト収録問題に基づく編集部集計)。
Q間違えた問題はどう復習すればいいですか?
誤答した選択肢のどこがずれていたかを解説で確認し、関連用語がある場合は用語集で定義に戻ってから再演習することをおすすめします。
モジュールの中の特定の名前だけを現在の名前空間へ取り込む書き方はどれか。
答えと解説を見る
正解は「from モジュール名 import 名前」である。この書き方はモジュールの中の指定した名前だけを現在の名前空間へ取り込むため、モジュール名を前に付けずに使える。import モジュール名 はモジュール自体を取り込む書き方で、中の名前を使うときはモジュール名を前に付ける必要がある。import 名前 from モジュール名 は語順が誤りで、Python の文法にこの並びは無い。include はモジュールの取り込みに使う語ではない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
組み込み関数 dir() の説明として正しいものはどれか。
答えと解説を見る
正解は「モジュール名を引数として渡すと、そのモジュールが定義している名前をソートされた文字列のリストとして返す」である。公式チュートリアルはdir()について、あるモジュールがどんな名前を定義しているか調べるために使われ、ソートされた文字列のリストを返すと説明している。引数を省略した場合にdir()が返すのは現在定義されている名前であり、インポート済みの標準モジュールの一覧ではない。dir()は組み込みの関数や変数の名前はリストせず、それらの一覧が必要なときは標準モジュールbuiltinsを使う。また、dir()は組み込み関数であり、dir(モジュール名)という形で呼び出すのが正しく、モジュール名.dir()という書き方はできない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
パッケージについて、ドット付きモジュール名の意味と__init__.pyの役割の組み合わせとして、正しいものはどれか。
答えと解説を見る
正解は「パッケージはPythonのモジュール名前空間をドット付きモジュール名で構造化する手段であり、モジュール名A.Bはパッケージ Aのサブモジュール Bを表す。ディレクトリをパッケージとして扱わせるには、原則として__init__.pyというファイルが必要である」である。公式チュートリアルはパッケージについて、Pythonのモジュール名前空間をドット付きモジュール名を使って構造化する手段だと説明しており、モジュール名A.Bはパッケージ Aのサブモジュール Bを表す。また、namespace packageという高度な機能を使う場合を除き、あるディレクトリをパッケージとして扱わせるには__init__.pyというファイルが必要になる。パッケージは1つのファイルへまとめるものではなくディレクトリ構造そのものであり、ドット付きモジュール名のAとBの順序を逆にした説明も誤りである。__init__.pyも実行を高速化するためのキャッシュファイルではない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
パッケージ内のモジュールから同じパッケージ内の別モジュールを参照する、明示的な相対importの書き方として正しいものはどれか。
答えと解説を見る
正解は「from . import echo」である。公式チュートリアルは、明示的な相対importでは先頭のドットで現在のパッケージや親パッケージを指定すると説明しており、from . import echoのように現在のパッケージ内のモジュールをドット1つで参照する例や、from .. import formatsのように親パッケージを参照する例、from ..filters import equalizerのように親パッケージの中の別のサブパッケージを参照する例を示している。import . echoのようにimportの直後にドットを置く書き方や、from echo import .のようにfromとimportの位置を入れ替えてドットを後ろに置く書き方、asの後ろにドットを置く書き方は、いずれも公式チュートリアルが示す相対importの構文と一致しない。相対importは現在のモジュールのパッケージ名を基準にするため、メインモジュールとして使われることを意図したモジュールでは絶対importを使うべきだとも説明されている。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
モジュールをインポートするときにインタプリタが検索する場所の順序について、公式チュートリアルの説明と一致するものはどれか。
答えと解説を見る
正解は「まず入力されたスクリプトのあるディレクトリ(ファイル未指定時はカレントディレクトリ)、次にPYTHONPATH環境変数に列挙されたディレクトリ、最後にインストール方法依存のデフォルトの場所の順に検索される」である。公式チュートリアルはモジュール検索パスの初期化順序について、まず入力されたスクリプトのあるディレクトリ(ファイルが指定されていない場合はカレントディレクトリ)、次にPYTHONPATH環境変数に列挙されたディレクトリのリスト、最後にインストール方法に依存するデフォルトの場所(慣例でsite-packagesディレクトリを含む)の順で検索すると説明している。スクリプトのあるディレクトリが標準ライブラリのパスよりも先頭に追加されるため、標準ライブラリと同じ名前のスクリプトを自分で作ると、意図せずそちらが優先してインポートされてしまう点にも注意が必要である。PYTHONPATHが最優先という説明や、インストール依存のデフォルトが最優先という説明、順序が規定されていないという説明はいずれも誤りである。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
変数sys.pathについて、公式チュートリアルの説明に合うものはどれか。
答えと解説を見る
正解は「sys.pathは文字列からなるリストで、インタプリタがモジュールを検索するときのパスを決定し、標準的なリスト操作で変更できる」である。公式チュートリアル6.2「標準モジュール」は、変数sys.pathについて「文字列からなるリストで、インタプリタがモジュールを検索するときのパスを決定します」と説明し、sys.path.append('/ufs/guido/lib/python')のように標準的なリスト操作で変更できる例を示している。したがって、sys.pathが読み取り専用の定数タプルであるという説明、dir()関数の別名だという説明、対話モードでのみ存在しスクリプト実行時には定義されないという説明は、いずれも公式の記載と一致しない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
モジュール内に書かれた実行文(関数定義以外の文)が実行されるタイミングについて、公式チュートリアルの説明に合うものはどれか。
答えと解説を見る
正解は「モジュールの実行文は、import文の中で最初にそのモジュール名が見つかったときにだけ実行される(ファイルがスクリプトとして実行される場合も実行される)」である。公式チュートリアル6.1「モジュールについてもうすこし」は、モジュールには関数定義に加えて実行文を入れることができ、これらの実行文はモジュールを初期化するためのもので、import文の中で最初にモジュール名が見つかったときにだけ実行されると説明している。したがって、importされるたびに毎回実行されるという説明、モジュール内の関数が呼び出されたときにだけ実行されるという説明、dir()関数が呼び出されたときにだけ実行されるという説明は、いずれも公式の記載と一致しない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
次のfibo.pyの末尾に書かれたコードについて、公式チュートリアルの説明に合うものはどれか。 if __name__ == "__main__": import sys fib(int(sys.argv[1]))
答えと解説を見る
正解は「このコードは、fibo.pyが"main"ファイルとしてスクリプト実行されたときにだけ実行され、モジュールとしてimportされた場合には実行されない」である。公式チュートリアル6.1.1「モジュールをスクリプトとして実行する」は、`python fibo.py <arguments>`のように実行すると__name__に__main__が設定される点を除いてimportしたときと同じようにコードが実行されると説明し、`if __name__ == "__main__":`というコードを追加することで、モジュールが"main"ファイルとして起動されたときだけコマンドラインを解釈するコードが実行され、モジュールがimportされた場合はそのコードが実行されないと説明している。したがって、常に実行されるという説明、importされたときだけ実行されるという説明、__name__という変数が存在せず構文エラーになるという説明は、いずれも公式の記載と一致しない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
Pythonのモジュールがコンパイル済みファイルとしてキャッシュされる仕組みについて、公式チュートリアルの説明に合うものはどれか。
答えと解説を見る
正解は「コンパイル済みモジュールは__pycache__ディレクトリのmodule.version.pycファイルとしてキャッシュされ、ソースの変更日時と比較して自動的に再コンパイルの要否が判断される」である。公式チュートリアル6.1.3「"コンパイル"されたPythonファイル」は、モジュールの読み込みを高速化するためPythonはコンパイル済みの各モジュールを__pycache__ディレクトリのmodule.version.pycファイルとしてキャッシュすると説明し、Pythonはソースの変更日時をコンパイル済みのものと比較し、再コンパイルが必要かどうかを完全に自動で確認すると説明している。また、.pycファイルで高速化されるのは読み込みにかかる時間だけでプログラムの実行自体が高速になるわけではなく、コンパイル済みモジュールはプラットフォーム非依存で異なるシステム間で共有できるとも説明している。したがって、実行自体が常に高速になるという説明、アーキテクチャに強く依存し共有に使えないという説明、鮮度確認の仕組みを持たず永久に更新されないという説明は、いずれも公式の記載と一致しない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
sound/effects/__init__.pyに__all__ = ["echo", "surround", "reverse"]が定義されているとき、from sound.effects import * を実行した結果について、公式チュートリアルの説明に合うものはどれか。
答えと解説を見る
正解は「__all__に挙げられた名前のリストが、from package import * が現れたときにimportすべきモジュール名のリストとして使われる」である。公式チュートリアル6.4.1「パッケージから*をimportする」は、import文の使う規約として、パッケージの__init__.pyコードに__all__という名前のリストが定義されていれば、from package import * が現れたときにimportすべきモジュール名のリストとしてそれが使われると説明し、sound/effects/__init__.pyに__all__ = ["echo", "surround", "reverse"]と書かれていれば、from sound.effects import * によってこの3つのサブモジュールがimportされる例を示している。したがって、__all__の定義が無視され全サブモジュールが自動検出されるという説明、__all__が定義されているとfrom...import *が構文エラーになるという説明、__all__がfrom package import *の挙動に一切影響しないという説明は、いずれも公式の記載と一致しない。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
fibo.py に関数 fib と fib2 が定義されている。インタープリタで from fibo import fib, fib2 を実行したあと、fib(500) と fibo.fib(500) をそれぞれ実行した。公式チュートリアルの説明に合う結果はどれか。
答えと解説を見る
正解は「fib(500) は実行できるが、fibo という名前は定義されないので fibo.fib(500) は名前のエラーになる」である。公式チュートリアルは、from fibo import fib, fib2 のように import 文には、モジュール内の名前を import を実行しているモジュールの名前空間に直接取り込む変型があり、この操作は import の対象となるモジュール名をローカルな名前空間に取り入れないと説明している。上の例では fibo は定義されない。取り込んだ fib と fib2 は、モジュール名なしでそのまま呼び出せる。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
モジュール fibo に、fib、fib2、および名前が _helper の関数が定義されている。インタープリタで from fibo import * を実行したときの説明として、公式チュートリアルに合うものはどれか。
答えと解説を見る
正解は「アンダースコア(_)で始まる名前を除いて、すべての名前がインポートされる」である。公式チュートリアルは、from fibo import * がアンダースコア(_)で始まるものを除いてすべての名前をインポートすると説明している。殆どの場面で使われないのは、未知の名前がインタープリターに読み込まれて定義済みの名前を上書きする可能性があるためである。一般的に、モジュールやパッケージから * を import するやり方は、しばしば可読性に乏しいコードになるため賛同されない。対話セッションでキータイプの量を減らすために使うのは構わないとされている。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
fibo.py に関数 fib が定義されている。インタープリタで import fibo as fib を実行した直後に fib(500) の形で fib 関数を呼び出したい。公式チュートリアルの説明に基づく判断として正しいものはどれか。
答えと解説を見る
正解は「fib はモジュール fibo を指す名前になるので、関数は fib.fib(500) と書いて呼び出す」である。公式チュートリアルは、モジュール名の後に as が続いていた場合は as の後ろの名前を直接、インポートされたモジュールが束縛すると説明している。import fibo as fib は実質的に import fibo と同じ方法でモジュールをインポートし、唯一の違いはモジュールを fib という名前で取り扱えることである。この形は from が付いた from fibo import fib as fibonacci でも使え、同じ効果が得られる。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
対話セッションで import fibo を実行したあと、別の端末で fibo.py の内容を書き換えた。同じセッションのまま、修正後の fibo.py を読み込み直すための方法として、公式チュートリアルの説明に合うものはどれか。
答えと解説を見る
正解は「インタープリタを再起動するか、直したいモジュールが1つだけなら importlib.reload(fibo) を使う」である。公式チュートリアルは、実行効率上の理由で各モジュールはインタープリタの1セッションごとに1回だけ import されると説明している。そのためモジュールを修正した場合は、インタープリタを再起動するか、その場で手直ししてテストしたいモジュールが1つだけなら importlib.reload(modulename) のように importlib.reload() を使う。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)
各モジュールが自分のプライベートな名前空間を持つことの利点として、公式チュートリアルが述べているものはどれか。
答えと解説を見る
正解は「モジュールの作者は、ユーザのグローバル変数と偶然衝突する心配をせずに、グローバル変数をモジュールで使える」である。公式チュートリアルは、各々のモジュールは自分のプライベートな名前空間を持ち、モジュールで定義されている関数はこの名前空間をグローバルな名前空間として使うため、モジュールの作者はユーザのグローバル変数と偶然衝突する心配をせずにグローバル変数をモジュールで使えると説明している。この仕組みのおかげで、モジュール側で定義した変数や関数の名前が、利用する側のプログラムの名前と意図せずぶつかって上書きされる事故を避けられる。
https://docs.python.org/ja/3/tutorial/modules.html (Python公式チュートリアル 第6章 モジュール)