Python 3 エンジニア認定基礎試験 モジュールと入出力 問題

ゆめさくが作った練習問題です。本試験の問題ではありません。

モジュールと入出力の問題を8問、小分野ごとにまとめました。選ぶと、その場で正誤と解説が出ます。

ログインなしで解けます。答えはこのブラウザの中だけに残り、どこにも送りません。

この分野の小分野

  • モジュールと入出力(8問)

モジュールと入出力の問題

8 問

選ぶと、すぐに正誤と解説が出ます。選んだ答えは変えられません。

  1. モジュールと入出力

    問 1次のコードを実行したときの出力として正しいものはどれですか。

    import math as m
    from math import sqrt
    print(m.floor(sqrt(10)), 'math' in dir())
  2. 問 2モジュールのファイル fibo.py を python fibo.py のようにスクリプトとして実行したとき、fibo.py の中の __name__ の値として正しいものはどれですか。

  3. 問 3import spam を実行したとき、インタープリタが spam を探す順として正しいものはどれですか。

  4. 問 4パッケージ pkg が下のファイルでできているとき、main.py を実行したときの出力として正しいものはどれですか。

    # pkg/__init__.py
    __all__ = ['a']
    
    # pkg/a.py
    X = 1
    
    # pkg/b.py
    Y = 2
    
    # main.py
    from pkg import *
    print('a' in dir(), 'b' in dir())
  5. 問 5パッケージ sound のサブモジュール sound.effects.surround の中で、同じ sound.effects にある echo を相対 import する書き方として正しいものはどれですか。

  6. 問 6次のコードを実行したときの出力として正しいものはどれですか。

    name = 'py'
    n = 7
    print(f'[{name:4}][{n:4}] {name!r}')
  7. 問 7次のコードを実行したときの出力として正しいものはどれですか。

    print('{1}-{0}-{x}'.format('A', 'B', x=repr('C')))
  8. 問 8次のコードを実行したときの出力として正しいものはどれですか。

    import json
    with open('t.txt', 'w') as f:
        f.write('ab\n')
    with open('t.txt', 'a') as f:
        f.write(json.dumps(['a', 1]))
    with open('t.txt') as f:
        first = f.readline()
        rest = f.read()
    print(repr(first), rest, f.closed)

8 問中 0 問に答えました

解説の一覧

解いたあとに読み返せるよう、全問の解説を並べています。問いを開くと解説が出ます。

モジュールと入出力

問1次のコードを実行したときの出力として正しいものはどれですか。
import math as m
from math import sqrt
print(m.floor(sqrt(10)), 'math' in dir())

正解は「3 False」です。import math as m は math モジュールを m という名前に結び付けます。from math import sqrt は sqrt を今の名前空間に直接取り込みますが、モジュールの名前 math は取り込みません。sqrt(1⁠0) は約 3.1⁠6 で、m.floor はそれ以下の最大の整数 3 を返します。引数なしの dir() は今定義されている名前のリストを返し、そこにあるのは m と sqrt で math はないので False です。「True」は from import や as でも math という名前ができると考えた誤りです。m も sqrt も使える名前なので NameError にはなりません。floor は整数を返すので 3.0 にはなりません。 出典 https://docs.python.org/ja/3/tutorial/modules.html#more-⁠on-⁠modules

問2モジュールのファイル fibo.py を python fibo.py のようにスクリプトとして実行したとき、fibo.py の中の __name__ の値として正しいものはどれですか。

正解は「'__main__'」です。モジュールをスクリプトとして実行すると、中のコードは import したときと同じように実行されますが、__name__ には文字列 '__main__' が入ります。この違いを使い、末尾に if __name__ == "__main__" の節を書くと、スクリプトとして起動したときだけ動き、import されたときには動かないコードを書けます。'fibo' は import fibo で読み込まれたときの値で、そのときはモジュール名が入ります。拡張子の付いた 'fibo.py' が入ることはありません。__name__ は常に文字列で、None にはなりません。 出典 https://docs.python.org/ja/3/tutorial/modules.html#executing-⁠modules-⁠as-⁠scripts

問3import spam を実行したとき、インタープリタが spam を探す順として正しいものはどれですか。

正解は「組み込みモジュールを探し、なければ sys.path のディレクトリを探す」です。インタープリタはまず spam という名前の組み込みモジュールを探し、見つからなければ spam.py というファイルを sys.path にあるディレクトリのリストから探します。sys.path は、入力されたスクリプトのあるディレクトリ、PYTHONPATH、インストールで決まるデフォルトの場所から初期化され、プログラムから変更することもできます。順が逆の選択肢は、組み込みモジュールが先に探されることを見落とした誤りです。カレントディレクトリだけ、PYTHONPATH だけを探すのではなく、どちらも sys.path を作る一部です。 出典 https://docs.python.org/ja/3/tutorial/modules.html#the-⁠module-⁠search-⁠path

問4パッケージ pkg が下のファイルでできているとき、main.py を実行したときの出力として正しいものはどれですか。
# pkg/__init__.py
__all__ = ['a']

# pkg/a.py
X = 1

# pkg/b.py
Y = 2

# main.py
from pkg import *
print('a' in dir(), 'b' in dir())

正解は「True False」です。ディレクトリをパッケージとして扱わせるには __init__.py を置きます。from package import * では、__init__.py に __all__ というリストがあれば、そこに挙がった名前のサブモジュールだけを import します。pkg の __all__ は ['a'] なので、a は import されて dir() に現れ、b は import されないので現れません。「True True」は * がパッケージの全てのサブモジュールを読み込むと考えた誤りです。「False False」は * がサブモジュールを 1 つも読み込まないと考えた誤りで、それは __all__ がなく、ほかで読み込まれてもいないときの話です。__all__ に挙がった a は実在するので ImportError にもなりません。 出典 https://docs.python.org/ja/3/tutorial/modules.html#importing-⁠from-⁠a-⁠package

問5パッケージ sound のサブモジュール sound.effects.surround の中で、同じ sound.effects にある echo を相対 import する書き方として正しいものはどれですか。

正解は「from . import echo」です。明示的な相対 import は from module import name の形の import 文で書き、先頭のドットで現在のパッケージや親のパッケージを示します。ドット 1 つは今のモジュールが属するパッケージ、この場合は sound.effects を指すので、from . import echo で兄弟の echo を読み込めます。import .echo のように import の形で相対の指定は書けません。ドット 2 つは 1 つ上の親パッケージ sound を指すので、sound.effects の echo には届きません。as の後ろには名前を書くもので、ドットは書けません。相対 import は今のモジュールのパッケージ名を基にするので、メインモジュールでは絶対 import を使います。 出典 https://docs.python.org/ja/3/tutorial/modules.html#intra-⁠package-⁠references

問6次のコードを実行したときの出力として正しいものはどれですか。
name = 'py'
n = 7
print(f'[{name:4}][{n:4}] {name!r}')

正解は「[py ][ 7] 'py'」です。f-⁠string では式の後ろのコロンに続けて書式指定子を書けます。コロンの後ろの整数は最小の文字幅で、揃え方を指定しないときは、文字列は左詰め、数値は右詰めになります。name は 'py' なので幅 4 で左詰めの 'py '、n は 7 なので幅 4 で右詰めの ' 7' です。!r は値に repr() を当てるので、文字列は引用符付きの 'py' と表示されます。1 つめは文字列も右詰めになると考えた誤りです。2 つめは数値も左詰めになると考えた誤りです。4 つめは !r を付けても引用符が付かないと考えた誤りです。 出典 https://docs.python.org/ja/3/library/string.html#formatspec

問7次のコードを実行したときの出力として正しいものはどれですか。
print('{1}-{0}-{x}'.format('A', 'B', x=repr('C')))

正解は「B-⁠A-'C'」です。str.format() では、波括弧の中の数字は format() に渡した引数の位置を表します。{1} は 2 番目の 'B'、{0} は 1 番目の 'A' に置き換わります。{x} はキーワード引数 x の値に置き換わり、x には repr('C') の結果が入っています。repr() はインタープリタが読める表現を返すので、文字列には引用符が付いて 'C' になります。「A-⁠B」で始まる 2 つは、数字に関係なく渡した順に埋まると考えた誤りです。「B-⁠A-⁠C」は repr() が str() と同じく引用符なしの文字列を返すと考えた誤りです。 出典 https://docs.python.org/ja/3/tutorial/inputoutput.html#the-⁠string-⁠format-⁠method

問8次のコードを実行したときの出力として正しいものはどれですか。
import json
with open('t.txt', 'w') as f:
    f.write('ab\n')
with open('t.txt', 'a') as f:
    f.write(json.dumps(['a', 1]))
with open('t.txt') as f:
    first = f.readline()
    rest = f.read()
print(repr(first), rest, f.closed)

正解は「'ab\n' ["a", 1] True」です。モード 'w' で開いて 'ab' と改行を書き、モード 'a' で開くと、書く内容はファイルの終わりに追記されます。json.dumps(['a', 1]) は JSON の文字列 ["a", 1] を返し、JSON では文字列を二重引用符で囲みます。readline() は 1 行を読み、末尾の改行文字を残すので、repr で見ると 'ab\n' です。残りを read() で読むと JSON の行が得られます。with を抜けるとファイルは自動で閉じるので、f.closed は True です。改行の付かない 'ab' は readline が改行を取り除くと考えた誤りです。['a', 1] は JSON が Python と同じ単引用符で書かれると考えた誤りです。False は with を抜けてもファイルが開いたままと考えた誤りです。 出典 https://docs.python.org/ja/3/tutorial/inputoutput.html#methods-⁠of-⁠file-⁠objects

ほかの分野

Python 3 エンジニア認定基礎試験の頁に、6分野の入口と試験の案内があります。

続きはゆめさくで

試験の知識を仕事につなげる一歩を、ここにまとめています。