第4章 制御構造ツール(40問中9問)
Python3基礎試験の関数注釈とdocstringの実行結果
docstring は関数の最初の文字列で __doc__ に入り、型の注釈は __annotations__ に入るだけで実行時に検査されません。
どちらも第4章の公式チュートリアルにある内容で、実行結果で確かめます。
この記事の目次
公式情報の確認
試験日、料金、申込条件、試験方式など変動する情報は、公式情報を最終確認してください。
試験の出題範囲・実施要項は変動するため、受験前に公式情報を確認してください。
docstringの書き方と__annotations__の中身
コードはすべて説明用に作った例で、公式の問題は転載していません。結果はPython 3.9.6で実行して確かめています。
- 関数本体の最初の文が文字列リテラルなら docstring で、関数の __doc__ から読める。文字列がなければ __doc__ は None
- docstring の1行目は、目的を短くまとめて大文字で始めピリオドで終える。続きを書くなら2行目は空行にする
- アノテーションは、引数は「名前: 式」、戻り値は「-> 式」で書き、__annotations__ に辞書として入る。戻り値は 'return' のキー
- アノテーションは完全にオプションで、関数の他の部分には影響しない。型の違う値を渡してもエラーにならない
docstringと__doc__
公式チュートリアルによると、関数本体の最初の文は文字列リテラルにすることもでき、その文字列を関数のドキュメンテーション文字列(documentation string)、または docstring と呼びます。公式は、自分が書くコードにドキュメンテーション文字列を入れるのはよい習慣だと述べています。
| コード | 実行結果 | ひとこと |
|---|---|---|
def doc():
"""1行目の要約。"""
pass
print(doc.__doc__) | 1行目の要約。 | 本体の最初の文字列リテラルが __doc__ に入る |
def plain(a, b):
return a + b
print(plain.__doc__) | None | 文字列を書かなければ __doc__ は None |
def h(x):
y = 1
"""2行目の文字列"""
return x
print(h.__doc__) | None | 最初の文でなければ docstring にならない |
def g(x):
"三重引用符でなくてもよい"
return x
print(g.__doc__) | 三重引用符でなくてもよい | 最初の文が文字列リテラルであればよい |
docstring になるのは、関数本体の最初の文だけです。2行目に書いた文字列は、ただの式として実行されるだけで、__doc__ は None のままでした。
書き方の慣習として、公式チュートリアルは次の3点を挙げています。最初の行にはオブジェクトの目的を短く簡潔にまとめ、名前や型は明記しません。この行は大文字で始め、ピリオドで終えます。さらに書く行があるときは、2行目を空行にして、まとめの行と残りを分けます。
docstring の中に実行例を書いて自動で検査する仕組みが doctest です。違いはdoctest と unittest の比較で整理しています。
関数のアノテーションと__annotations__
公式チュートリアルによると、関数アノテーションはユーザ定義関数で使用される型についての完全にオプションなメタデータ情報です。アノテーションは関数の __annotations__ 属性に辞書として格納されます。パラメータアノテーションはパラメータ名の後にコロンを続け、その後にアノテーションの値として評価される式を置きます。戻り値アノテーションは、パラメータリストと def 文の終わりのコロンの間に、リテラル -> に続けて式を置きます。
| コード | 実行結果 | ひとこと |
|---|---|---|
def f(ham: str, eggs: str = 'eggs') -> str:
return ham + ' and ' + eggs
print(f.__annotations__) | {'ham': <class 'str'>, 'eggs': <class 'str'>, 'return': <class 'str'>} | 引数は「名前: 式」、戻り値は「-> 式」。戻り値は 'return' のキーに入る |
f('spam') | 'spam and eggs' | 既定値は注釈のあとに = で書く。呼び出し結果は注釈の有無で変わらない |
def plain(a, b):
return a + b
print(plain.__annotations__) | {} | 注釈を書かなければ空の辞書 |
戻り値の注釈は、辞書の 'return' というキーに入ります。引数に既定値があるときは、f(ham: str, eggs: str = 'eggs') のように注釈、等号、既定値の順に書きます。
型を書いても検査されない
公式チュートリアルは、アノテーションは関数の他の部分には何も影響を与えないと述べています。実際に int と注釈した関数へ文字列を渡して確かめます。
| コード(2行目以降は上の add を使う) | 実行結果 | ひとこと |
|---|---|---|
def add(a: int, b: int) -> int:
return a + b
add(1, 2) | 3 | int と書いた引数に int を渡せば当然動く |
add('x', 'y') | 'xy' | str を渡してもエラーにならず、文字列の連結として動く |
add.__annotations__ | {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>} | 注釈は記録されるだけで、型の検査には使われない |
型を注釈しても、Python は実行時に引数の型を検査しません。add('x', 'y') はエラーにならず 'xy' を返しました。注釈は読む人やツールのための情報で、動作は注釈の有無で変わりません。
Python3エンジニア認定基礎試験の学習に使う書籍(Amazon)
PRよくある質問
docstringとは何ですか?
公式チュートリアルによると、関数本体の最初の文が文字列リテラルのとき、その文字列を関数のドキュメンテーション文字列(docstring)と呼びます。ドキュメンテーション文字列を使ったツールには、オンライン文書や印刷文書を自動的に生成したり、ユーザが対話的にコードから直接閲覧できるようにするものがあります。
docstringの1行目には何を書きますか?
公式チュートリアルによると、最初の行にはオブジェクトの目的を短く簡潔にまとめます。オブジェクトの名前や型は明記しないようにし、この行は大文字で始めてピリオドで終えます。さらに書く場合は2行目を空行にして、まとめの行と残りの記述部分を分けます。
関数のアノテーションを書くと、型の違う値を渡したときエラーになりますか?
なりません。公式チュートリアルによると、アノテーションはユーザ定義関数で使用される型についての完全にオプションなメタデータ情報で、関数の __annotations__ 属性に辞書として格納され、関数の他の部分には何も影響を与えません。このページの add('x', 'y') もエラーにならず 'xy' を返しました。
戻り値のアノテーションはどう書きますか?
公式チュートリアルによると、パラメータアノテーションはパラメータ名の後にコロンを続け、その後に式を置きます。戻り値アノテーションは、パラメータリストと def 文の終わりを表すコロンの間に、リテラル -> に続けて式を置きます。
第4章の制御構造ツールは、何問出ますか?
このサイトが整理した公式の章別出題数では、40問中9問(22.5%)で、全章の中で最多です。if文、for文とrange()、break・continue、match文、関数の定義と引数が含まれます。
