4. その他の制御フローツール
***************************

前章で紹介した "while" 文の他にも、 Python にはいくつか制御フローツー
ルがあり、本章で説明します。


4.1. "if" 文
============

おそらく最もおなじみの文型は "if" 文でしょう。例えば:

   >>> x = int(input("Please enter an integer: "))
   Please enter an integer: 42
   >>> if x < 0:
   ...     x = 0
   ...     print('Negative changed to zero')
   ... elif x == 0:
   ...     print('Zero')
   ... elif x == 1:
   ...     print('Single')
   ... else:
   ...     print('More')
   ...
   More

ゼロ個以上の "elif" 部を使うことができ、 "else" 部を付けることもできま
す。キーワード '"elif"' は 'else if' を短くしたもので、過剰なインデン
トを避けるのに役立ちます。一連の "if" ... "elif" ... "elif" ...  は、
他の言語における "switch" 文や "case" 文の代用となります。

同じ値を複数の定数と比較する場合や、特定の型や属性を確認する場合には、
"match" 文も便利です。詳細は match 文 を参照してください。


4.2. "for" 文
=============

Python の "for" 文は、読者が C 言語や Pascal 言語で使いなれているかも
しれない "for" 文とは少し違います。 (Pascal のように) 常に等差数列にわ
たる反復を行ったり、 (C のように) 繰返しステップと停止条件を両方ともユ
ーザが定義できるようにするのとは違い、Python の "for" 文は、任意のシー
ケンス型 (リストまたは文字列) にわたって反復を行います。反復の順番はシ
ーケンス中に要素が現れる順番です。例えば:

   >>> # 文字列の長さを計測:
   >>> words = ['cat', 'window', 'defenestrate']
   >>> for w in words:
   ...     print(w, len(w))
   ...
   cat 3
   window 6
   defenestrate 12

コレクションを反復処理しながらそのコレクションを変更するコードを正しく
書くのは難しいことがあります。通常は、コレクションのコピーを反復処理す
るか、新しいコレクションを作成する方が簡単です。

   # コレクション作成
   users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}

   # 方針:  コピーを反復
   for user, status in users.copy().items():
       if status == 'inactive':
           del users[user]

   # 方針:  新コレクション作成
   active_users = {}
   for user, status in users.items():
       if status == 'active':
           active_users[user] = status


4.3. "range()" 関数
===================

数列にわたって反復を行う必要がある場合、組み込み関数 "range()"  が便利
です。この関数は等差数列を生成します。

   >>> for i in range(5):
   ...     print(i)
   ...
   0
   1
   2
   3
   4

指定した終端値は生成されるシーケンスには入りません。"range(10)" は 10
個の値を生成し、長さ 10 のシーケンスにおける各項目のインデクスとなりま
す。range を別の数から開始したり、他の増加量 (負でも; 増加量は時に 'ス
テップ(step)' と呼ばれることもあります) を指定することもできます:

   >>> list(range(5, 10))
   [5, 6, 7, 8, 9]

   >>> list(range(0, 10, 3))
   [0, 3, 6, 9]

   >>> list(range(-10, -100, -30))
   [-10, -40, -70]

あるシーケンスにわたってインデクスで反復を行うには、 "range()" と
"len()" を次のように組み合わせられます:

   >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
   >>> for i in range(len(a)):
   ...     print(i, a[i])
   ...
   0 Mary
   1 had
   2 a
   3 little
   4 lamb

しかし、多くの場合は "enumerate()" 関数を使う方が便利です。 ループのテ
クニック を参照してください。

range を直接出力すると変なことになります:

   >>> range(10)
   range(0, 10)

"range()" が返すオブジェクトは、いろいろな点でリストであるかのように振
る舞いますが、本当はリストではありません。これは、イテレートした時に望
んだ数列の連続した要素を返すオブジェクトです。しかし実際にリストを作る
わけではないので、スペースの節約になります。

このようなオブジェクトを *イテラブル* と呼びます。つまり、要素が *尽き
る* まで順に取得できるものを必要とする関数や構文で使えます。これまでに
見た "for" 文がそのような構文の例で、イテラブルを受け取る関数の例には
"sum()" があります。

   >>> sum(range(4))  # 0 + 1 + 2 + 3
   6

イテラブルを返す関数や、イテラブルを引数に取る関数は後でさらに紹介しま
す。 データ構造 の章では "list()" について詳しく説明します。


4.4. "break" 文と "continue" 文
===============================

"break" 文は、その文を囲む最も内側の "for" ループまたは "while" ループ
を抜けます。

   >>> for n in range(2, 10):
   ...     for x in range(2, n):
   ...         if n % x == 0:
   ...             print(f"{n} は {x} * {n//x} と等しい")
   ...             break
   ...
   4 は 2 * 2 と等しい
   6 は 2 * 3 と等しい
   8 は 2 * 4 と等しい
   9 は 3 * 3 と等しい

"continue" 文はループの次のイテレーションを実行します:

   >>> for num in range(2, 10):
   ...     if num % 2 == 0:
   ...         print(f"偶数 {num} を見つけた")
   ...         continue
   ...     print(f"奇数 {num} を見つけた")
   ...
   偶数 2 を見つけた
   奇数 3 を見つけた
   偶数 4 を見つけた
   奇数 5 を見つけた
   偶数 6 を見つけた
   奇数 7 を見つけた
   偶数 8 を見つけた
   奇数 9 を見つけた


4.5. ループの "else" 節
=======================

"for" または "while" ループ中の "break" 文は "else" 節と対になる場合が
あります。"break" を実行せずにループが終了すると、"else" 節が実行され
ます。

"for" 文の場合、 "else" 節はループ処理の最後のイテレーションが実行され
たあと、つまりbreakが発生しなかった場合に実行されます。

"while" 文の場合は、ループ条件が偽となったあとに実行されます。

どちらのループでも、ループが "break" によって終了した場合は "else" 句
は **実行されません**。当然、 "return" や例外の発生によってループが途
中で終了した場合にも、"else" 節の実行はスキップされます。

その例として、素数を探索する "for" 文を以下に示します:

   >>> for n in range(2, 10):
   ...     for x in range(2, n):
   ...         if n % x == 0:
   ...             print(n, 'equals', x, '*', n//x)
   ...             break
   ...     else:
   ...         # 因数が見つからないとループは最後まで実行される
   ...         print(n, 'is a prime number')
   ...
   2 is a prime number
   3 is a prime number
   4 equals 2 * 2
   5 is a prime number
   6 equals 2 * 3
   7 is a prime number
   8 equals 2 * 4
   9 equals 3 * 3

(そう、これは正しいコードです。よく見てください: "else" 節は "if" 文
**ではなく** 、 "for" ループに属しています。)

else 節を理解するには、ループ内の "if" と対になると考える方法がありま
す。ループが実行されるにつれて if/if/if/else のように処理が進みます。
"if" はループの内側にあり、何度も実行されます。条件が一度でも真になれ
ば "break" が実行されます。一度も真にならなければ、ループの外側にある
"else" 節が実行されます。

ループの "else" 句は、 "if" 文の "else" よりも "try" 文の "else" に似
ています。 "try" 文の "else" 句は例外が発生しなかった時に実行され、ル
ープの "else" 句は "break" されなかった場合に実行されます。 "try" 文と
例外についての詳細は 例外を処理する を参照してください。


4.6. "pass" 文
==============

"pass" 文は何もしません。 "pass" は、文を書くことが構文上要求されてい
るが、プログラム上何の動作もする必要がない時に使われます:

   >>> while True:
   ...     pass  # キーボード割り込み(Ctrl+C)のためのビジーウェイト
   ...

これは最小のクラスを作るときによく使われる方法です:

   >>> class MyEmptyClass:
   ...     pass
   ...

"pass" のもう 1 つの使い道は、新しいコードを書いているときの関数や条件
文の仮置きの本体としてです。こうすることで、より抽象的なレベルで考え続
けられます。 "pass" は何事も無く無視されます

   >>> def initlog(*args):
   ...     pass   # ここを忘れずに実装すること!
   ...

この最後の例で、多くの人は "pass" ではなく省略記号リテラル "..." を使
います。 この使い方は Python に対して特別な意味はなく、言語定義の一部
でもありません（ここにはどんな定数式でも使えます）が、 "..." は慣例的
にプレースホルダ本体としても使われています。 Ellipsis オブジェクト を
参照してください。


4.7. "match" 文
===============

"match" 文は式を受け取り、その値を1つ以上の case ブロックに指定された
パターンと順に比較します。表面的には C、Java、JavaScript などの switch
文に似ていますが、Rust や Haskell などのパターンマッチングにより近いも
のです。最初にマッチしたパターンのブロックだけが実行されます。また、値
から構成要素 (シーケンスの要素やオブジェクトの属性) を取り出して変数に
代入することもできます。どの case にもマッチしなければ、どの分岐も実行
されません。

最も単純な形式では、対象の値を1つ以上のリテラルと比較します。

   def http_error(status):
       match status:
           case 400:
               return "Bad request"
           case 404:
               return "Not found"
           case 418:
               return "I'm a teapot"
           case _:
               return "Something's wrong with the internet"

最後のブロックについて: 変数名 "_" は *ワイルドカード* の働きをし、マ
ッチに絶対失敗しません。

複数のリテラルを "|" ("or")を使用して組み合わせて1つのパターンにできま
す:

   case 401 | 403 | 404:
       return "Not allowed"

パターンはアンパック代入に似た形で書くことができ、変数に値を結びつける
ために使えます。

   # point(座標) は (x, y) のタプル
   match point:
       case (0, 0):
           print("原点")
       case (0, y):
           print(f"Y={y}")
       case (x, 0):
           print(f"X={x}")
       case (x, y):
           print(f"X={x}, Y={y}")
       case _:
           raise ValueError("座標ではない")

このコードは注意して見てください！ 最初のパターンには2つのリテラルがあ
り、上で示したリテラルパターンの拡張と考えることができます。 しかし次
の2つのパターンはリテラルと変数の組み合わせのため、対象("point")から値
を取り出して変数に *結びつけ* ます。 4番目のパターンは2つの値を取り込
みます。 これは、アンパック代入 "(x, y) = point" と概念的に似ています
。

データを構造化するためにクラスを使っている場合は、クラス名の後にコンス
トラクターに似た引数リストを指定できます。これにより属性の値を変数に取
り込めます。

   class Point:
       def __init__(self, x, y):
           self.x = x
           self.y = y

   def where_is(point):
       match point:
           case Point(x=0, y=0):
               print("原点")
           case Point(x=0, y=y):
               print(f"Y={y}")
           case Point(x=x, y=0):
               print(f"X={x}")
           case Point():
               print("それ以外のどこか")
           case _:
               print("座標ではない")

属性の順序が定まっている一部の組み込みクラス (データクラスなど) では位
置引数を使えます。自分のクラスに "__match_args__" 特殊属性を設定して、
パターン内での各属性の位置を定義することもできます。この属性を ("x",
"y") に設定すると、次のパターンはすべて等価になります (いずれも "y" 属
性の値を "var" 変数に結びつけます)。

   Point(1, var)
   Point(1, y=var)
   Point(x=1, y=var)
   Point(y=var, x=1)

おすすめのパターンの読み方は、パターンが、代入文の左辺に配置するものを
拡張した形式であるとみなすことです。 これにより、どの変数になにが代入
されるかが分かります。 単独の名前（上記の "var" など）だけがマッチ文で
値が代入されます。ドット付きの名前（"foo.bar" など）、属性名（上記の
"x="、"y=" など ）、クラス名（名前の後ろの "(...)"  によって判別される
。上記の "Point" など）には値は代入されません。

パターンは任意にネストできます。 例えば、"__match_args__" を追加した
"Point" クラスのインスタンスからなる短いリストがある場合、次のようにマ
ッチできます。

   class Point:
       __match_args__ = ('x', 'y')
       def __init__(self, x, y):
           self.x = x
           self.y = y

   match points:
       case []:
           print("座標が存在しない")
       case [Point(0, 0)]:
           print("原点")
       case [Point(x, y)]:
           print(f"1つの座標 {x}, {y}")
       case [Point(0, y1), Point(0, y2)]:
           print(f"Y軸の {y1}, {y2} に2つの座標")
       case _:
           print("それ以外のどこか")

パターンには「ガード」と呼ばれる "if" 節を追加できます。ガードが偽なら
、"match" は次の case ブロックのパターンとのマッチを試みます。値の取り
込みはガードの評価より前に行われることに注意してください。

   match point:
       case Point(x, y) if x == y:
           print(f"Y=X at {x}")
       case Point(x, y):
           print(f"対角線上ではない")

この文には、ほかにも次のような重要な特徴があります:

* アンパック代入のように、タプルとリストのパターンでは正確に同じ意味で
  、任意のシーケンスと一致します。重要な例外として、イテレーターや文字
  列ではマッチしません。

* シーケンスパターンは拡張アンパックをサポート: "[x, y, *rest]" と
  "(x, y, *rest)" はアンパック代入として同じように動作します。"*" のあ
  との変数名は "_" でもよく、そのため "(x, y, *_)" は最低でも2つのアイ
  テムを持つシーケンスにマッチし、残りのアイテムは変数に結びつけられま
  せん。

* マッピングパターン: "{"bandwidth": b, "latency": l}" は辞書から
  ""bandwidth"" と ""latency"" の値を取り込みます。シーケンスパターン
  とは異なり、それ以外のキーは無視されます。アンパッキングのような
  "**rest" もサポートされています（しかし、 "**_" は冗長なため禁止され
  ています）。

* "as" キーワードを使うと、サブパターンにマッチした値を変数に取り込め
  ます。

     case (Point(x1, y1), Point(x2, y2) as p2): ...

  この例では入力から2番目の要素を "p2" として取り込みます（入力が2つの
  ポイントのシーケンスである場合）

* ほとんどのリテラルは値が等しいかどうかで比較しますが、シングルトンの
  "True"、"False"、"None" は同一のオブジェクトかどうかで比較します。

* 名前付きの定数もパターンで使えます。値を取り込む変数と解釈されないよ
  う、ドットを含む名前にする必要があります。

     from enum import Enum
     class Color(Enum):
         RED = 'red'
         GREEN = 'green'
         BLUE = 'blue'

     color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))

     match color:
         case Color.RED:
             print("I see red!")
         case Color.GREEN:
             print("Grass is green")
         case Color.BLUE:
             print("I'm feeling the blues :(")

より詳細な説明と追加の例は **PEP 636** にチュートリアル形式で記述して
あります。


4.8. 関数を定義する
===================

フィボナッチ数列 (Fibonacci series) を任意の上限値まで書き出すような関
数を作成できます:

   >>> def fib(n):    # n 未満のフィボナッチ数列を出力する
   ...     """n 未満のフィボナッチ数列を出力する。"""
   ...     a, b = 0, 1
   ...     while a < n:
   ...         print(a, end=' ')
   ...         a, b = b, a+b
   ...     print()
   ...
   >>> # 定義した関数を呼び出す:
   >>> fib(2000)
   0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

"def" は関数の *定義 (definition)* を導くキーワードです。 "def" の後に
は、関数名と仮引数を丸括弧で囲んだリストを続けなければなりません。関数
の実体を構成する実行文は次の行から始め、インデントされていなければなり
ません。

関数本体の最初の文は文字列リテラルにすることもできます。その場合、この
文字列は関数のドキュメンテーション文字列 (documentation string)、また
は *docstring* と呼ばれます。 (docstring については ドキュメンテーショ
ン文字列 でさらに扱っています。) ドキュメンテーション文字列を使ったツ
ールには、オンライン文書や印刷文書を自動的に生成したり、ユーザが対話的
にコードから直接閲覧できるようにするものがあります。自分が書くコードに
ドキュメンテーション文字列を入れるのはよい習慣です。書く癖をつけてくだ
さい。

関数を *実行 (execution)* すると、その関数のローカル変数に使う新しいシ
ンボルテーブル (symbol table) が作られます。 より正確には、関数内で変
数に値を代入すると、その値はローカルなシンボルテーブルに格納されます。
変数を参照するときは、まずローカルなシンボルテーブル、次に外側の関数の
ローカルなシンボルテーブル、その次にグローバルなシンボルテーブル、最後
に組み込み名のテーブルを検索します。 したがって、関数内からグローバル
変数や外側の関数の変数を参照することはできますが、直接値を代入すること
はできません。 ただし、グローバル変数を "global" 文で指定した場合や、
外側の関数の変数を "nonlocal" 文で指定した場合は例外です。

関数を呼び出す際の実際の引数 (実引数) は、関数が呼び出されるときに関数
のローカルなシンボルテーブル内に取り込まれます。そうすることで、実引数
は *値渡し (call by value)* で関数に渡されることになります (ここでの *
値 (value)* とは常にオブジェクトへの *参照(reference)* をいい、オブジ
ェクトの値そのものではありません) [1]。ある関数がほかの関数を呼び出す
ときや、自身を再帰的に呼び出すときには、新たな呼び出しのためにローカル
なシンボルテーブルが新たに作成されます。

関数定義は、現在のシンボルテーブルで関数名と関数オブジェクトを関連付け
ます。 インタープリタは、その名前が指すオブジェクトをユーザー定義関数
(user-defined function) として認識します。 他の名前も同じ関数オブジェ
クトを指すことができ、その名前を使って関数にアクセスできます。

   >>> fib
   <function fib at 10042ed0>
   >>> f = fib
   >>> f(100)
   0 1 1 2 3 5 8 13 21 34 55 89

他の言語出身の人からは、 "fib" は値を返さないので関数ではなく手続き
(procedure) だと異論があるかもしれませんね。技術的に言えば、実際には
"return" 文を持たない関数もややつまらない値ですが値を返しています。こ
の値は "None" と呼ばれます (これは組み込みの名前です)。 "None" だけを
書き出そうとすると、インタプリタは通常出力を抑制します。本当に出力した
いのなら、以下のように "print()" を使うと見ることができます:

   >>> fib(0)
   >>> print(fib(0))
   None

フィボナッチ数列を出力する代わりに、数列の値を含むリストを返す関数も簡
単に書けます。

   >>> def fib2(n):  # n 未満のフィボナッチ数列を返す
   ...     """n 未満のフィボナッチ数列を含むリストを返す。"""
   ...     result = []
   ...     a, b = 0, 1
   ...     while a < n:
   ...         result.append(a)    # 以下参照
   ...         a, b = b, a+b
   ...     return result
   ...
   >>> f100 = fib2(100)    # 関数を呼び出す
   >>> f100                # 結果を出力する
   [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

この例は Python の新しい機能を示しています:

* "return" 文は値を返して関数を終了します。式を指定しない "return" は
  "None" を返します。関数本体の末尾に到達した場合も "None" を返します
  。

* 文 "result.append(a)" では、リストオブジェクト "result" の *メソッド
  (method)* を呼び出しています。メソッドとは、オブジェクトに '属してい
  る' 関数のことで、 "obj" を何らかのオブジェクト (式であっても構いま
  せん)、 "methodname" をそのオブジェクトの型で定義されているメソッド
  名とすると、 "obj.methodname" と書き表されます。異なる型は異なるメソ
  ッドを定義しています。異なる型のメソッドで同じ名前のメソッドを持つこ
  とができ、あいまいさを生じることはありません。 (*クラス (class)* を
  使うことで、自前のオブジェクト型とメソッドを定義することもできます。
  クラス 参照) 例で示されているメソッド "append()" は、リストオブジェ
  クトで定義されています; このメソッドはリストの末尾に新たな要素を追加
  します。この例での "append()" は "result = result + [a]" と等価です
  が、より効率的です。


4.9. 関数定義についてもう少し
=============================

可変個の引数を伴う関数を定義することもできます。引数の定義方法には 3
つの形式があり、それらを組み合わせることができます。


4.9.1. デフォルトの引数値
-------------------------

もっとも便利なのは、一つ以上の引数に対してデフォルトの値を指定する形式
です。この形式を使うと、定義されている引数より少ない個数の引数で呼び出
せる関数を作成します:

   def ask_ok(prompt, retries=4, reminder='再試行してください!'):
       while True:
           reply = input(prompt)
           if reply in {'y', 'ye', 'yes'}:
               return True
           if reply in {'n', 'no', 'nop', 'nope'}:
               return False
           retries = retries - 1
           if retries < 0:
               raise ValueError('無効なユーザーの入力')
           print(reminder)

この関数はいくつかの方法で呼び出せます:

* 必須の引数のみ与える: "ask_ok('Do you really want to quit?')"

* 一つのオプション引数を与える: "ask_ok('OK to overwrite the file?',
  2)"

* 全ての引数を与える: "ask_ok('OK to overwrite the file?', 2, 'Come
  on, only yes or no!')"

この例では "in" キーワードが導入されています。このキーワードはシーケン
スが特定の値を含んでいるかどうか調べるのに使われます。

デフォルト値は、関数が定義された時点で、関数を *定義している* 側のスコ
ープ (scope) で評価されるので

   i = 5

   def f(arg=i):
       print(arg)

   i = 6
   f()

は "5" を出力します。

**重要な警告:** デフォルト値は1度しか評価されません。このことは、デフ
ォルト値がリスト、辞書、多くのクラスのインスタンスなどのミュータブルな
オブジェクトである場合に影響します。例えば、次の関数は呼び出されるたび
に渡された引数を蓄積します。

   def f(a, L=[]):
       L.append(a)
       return L

   print(f(1))
   print(f(2))
   print(f(3))

このコードは、以下を出力します

   [1]
   [1, 2]
   [1, 2, 3]

後続の関数呼び出しでデフォルト値を共有したくなければ、代わりに以下のよ
うに関数を書くことができます:

   def f(a, L=None):
       if L is None:
           L = []
       L.append(a)
       return L


4.9.2. キーワード引数
---------------------

関数を "kwarg=value" という形式の *キーワード引数* を使って呼び出すこ
ともできます。例えば、以下の関数:

   def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
       print("-- This parrot wouldn't", action, end=' ')
       print("if you put", voltage, "volts through it.")
       print("-- Lovely plumage, the", type)
       print("-- It's", state, "!")

は、1つの必須引数 ("voltage") と3つのオプション引数 ("state"、"action"
、"type") を受け付けます。この関数は以下のいずれかの方法で呼び出せます
。

   parrot(1000)                                          # 1つの位置引数
   parrot(voltage=1000)                                  # 1つのキーワード引数
   parrot(voltage=1000000, action='VOOOOOM')             # 2つのキーワード引数
   parrot(action='VOOOOOM', voltage=1000000)             # 2つのキーワード引数
   parrot('a million', 'bereft of life', 'jump')         # 3つの位置引数
   parrot('a thousand', state='pushing up the daisies')  # 1つの位置引数と1つのキーワード引数

が、以下の呼び出しは不適切です:

   parrot()                     # 必須の引数がない
   parrot(voltage=5.0, 'dead')  # キーワード引数の後ろにキーワードのない引数
   parrot(110, voltage=220)     # 同じ引数に対して2つの値を指定
   parrot(actor='John Cleese')  # 未知のキーワード引数

関数の呼び出しにおいて、キーワード引数は位置引数の後でなければなりませ
ん。渡されるキーワード引数は全て、関数で受け付けられる引数のいずれかに
対応していなければならず (例えば、"actor" はこの "parrot" 関数の引数と
して適切ではありません)、順序は重要ではありません。これはオプションで
ない引数でも同様です (例えば、"parrot(voltage=1000)" も適切です)。いか
なる引数も値を複数回は受け取れません。この制限により失敗する例は:

   >>> def function(a):
   ...     pass
   ...
   >>> function(0, a=0)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: function() got multiple values for argument 'a'

仮引数の最後に "**name" の形式のものがあると、それまでの仮引数に対応し
たものを除くすべてのキーワード引数が入った辞書 (マッピング型 --- dict
、frozendict を参照) を受け取ります。 "**name" は "*name" の形式をとる
、仮引数のリストを超えた位置引数の入った タプル を受け取る引数 (次の小
節で述べます) と組み合わせられます。 ("*name" は "**name" より前になけ
ればなりません)。 例えば、ある関数の定義を以下のようにすると:

   def cheeseshop(kind, *arguments, **keywords):
       print("-- Do you have any", kind, "?")
       print("-- I'm sorry, we're all out of", kind)
       for arg in arguments:
           print(arg)
       print("-" * 40)
       for kw in keywords:
           print(kw, ":", keywords[kw])

呼び出しは以下のようになり:

   cheeseshop("Limburger", "It's very runny, sir.",
              "It's really very, VERY runny, sir.",
              shopkeeper="Michael Palin",
              client="John Cleese",
              sketch="Cheese Shop Sketch")

もちろん以下のように出力されます:

   -- Do you have any Limburger ?
   -- I'm sorry, we're all out of Limburger
   It's very runny, sir.
   It's really very, VERY runny, sir.
   ----------------------------------------
   shopkeeper : Michael Palin
   client : John Cleese
   sketch : Cheese Shop Sketch

なお、複数のキーワード引数を与えた場合に、それらが出力される順序は、関
数呼び出しで与えられた順序と同じになります。


4.9.3. 特殊なパラメータ
-----------------------

デフォルトでは、引数は位置またはキーワードによる明示で Python 関数に渡
されます。 可読性とパフォーマンスのために、その引数が位置、位置または
キーワード、キーワードのどれで渡されるかを開発者が判定するのに関数定義
だけを見ればよいように、引数の渡され方を制限することには意味があります
。

関数定義は次のようになります:

   def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
         -----------    ----------     ----------
           |             |                  |
           |        位置またはキーワード    |
           |                                - キーワード専用
            -- 位置専用

ここで "/" と "*" は省略できます。 これらの記号を使うと、実引数を関数
に渡せる方法に応じて、仮引数が位置専用、位置またはキーワード、キーワー
ド専用のどれであるかを示せます。 キーワードパラメータは、名前付きパラ
メータとも呼ばれます。


4.9.3.1. 位置またはキーワード引数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

関数定義に "/" も "*" もない場合は、引数は位置またはキーワードで関数に
渡されます。


4.9.3.2. 位置専用引数
~~~~~~~~~~~~~~~~~~~~~

これをもう少し詳しく見てみると、特定の引数を *位置専用* と印を付けられ
ます。 *位置専用* の場合、引数の順序が重要であり、キーワードで引数を渡
せません。 位置専用引数は "/" （スラッシュ）の前に配置されます。 "/"
は、位置専用引数を残りの引数から論理的に分離するために使用されます。
関数定義に "/" がない場合、位置専用引数はありません。

"/" の後の引数は、 *位置またはキーワード* 、もしくは、 *キーワード専用
* です。


4.9.3.3. キーワード専用引数
~~~~~~~~~~~~~~~~~~~~~~~~~~~

引数をキーワード引数で渡す必要があることを示す *キーワード専用* として
引数をマークするには、引数リストの最初の *キーワード専用* 引数の直前に
"*" を配置します。


4.9.3.4. 関数の例
~~~~~~~~~~~~~~~~~

"/" および "*" といったマーカーに注意を払って、次の関数定義の例を見て
ください:

   >>> def standard_arg(arg):
   ...     print(arg)
   ...
   >>> def pos_only_arg(arg, /):
   ...     print(arg)
   ...
   >>> def kwd_only_arg(*, arg):
   ...     print(arg)
   ...
   >>> def combined_example(pos_only, /, standard, *, kwd_only):
   ...     print(pos_only, standard, kwd_only)

最も馴染みのある形式の最初の関数定義 "standard_arg"  は、呼び出し規約
に制限を設けておらず、引数は位置またはキーワードで渡されます:

   >>> standard_arg(2)
   2

   >>> standard_arg(arg=2)
   2

2番目の関数の "pos_only_arg" は、 "/" が関数定義にあるので、引数は位置
専用になります:

   >>> pos_only_arg(1)
   1

   >>> pos_only_arg(arg=1)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

3番目の関数 "kwd_only_arg" は、関数定義に "*" があるので、引数はキーワ
ード専用になります:

   >>> kwd_only_arg(3)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

   >>> kwd_only_arg(arg=3)
   3

そして最後の関数は3つの引数の種類を一つの関数定義の中で使用しています:

   >>> combined_example(1, 2, 3)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: combined_example() takes 2 positional arguments but 3 were given

   >>> combined_example(1, 2, kwd_only=3)
   1 2 3

   >>> combined_example(1, standard=2, kwd_only=3)
   1 2 3

   >>> combined_example(pos_only=1, standard=2, kwd_only=3)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: combined_example() got some positional-only arguments passed as keyword arguments: 'pos_only'

最後に、位置引数 "name" と "name" をキーとして持つ "**kwds" の間に潜在
的な衝突がある関数定義を考えてみましょう。

   def foo(name, **kwds):
       return 'name' in kwds

キーワード引数 "'name'" は常に最初の引数に結びつけられるため、この関数
が "True" を返す呼び出し方はありません。例えば次のようになります。

   >>> foo(1, **{'name': 2})
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: foo() got multiple values for argument 'name'
   >>>

しかし位置専用を示す "/" を使用すれば可能になります。 "name" は位置引
数として、そして "'name'" はキーワード引数のキーワードとして認識される
からです:

   >>> def foo(name, /, **kwds):
   ...     return 'name' in kwds
   ...
   >>> foo(1, **{'name': 2})
   True

言い換えると、位置専用引数であれば、その名前を "**kwds" の中で使用して
も、曖昧にならないということです。


4.9.3.5. 要約
~~~~~~~~~~~~~

関数定義でどの種類の引数を使うかは、用途に応じて決めます。

   def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

ガイドとしては、

* 呼び出し側が引数名を使って指定できないようにしたい場合は、位置専用引
  数を使います。引数名に特に意味がない場合や、呼び出し時の引数の順序を
  固定したい場合、いくつかの位置引数と任意のキーワード引数を受け取りた
  い場合に便利です。

* 引数名に意味があり、名前を明示した方が関数定義を理解しやすい場合や、
  呼び出し側が引数の位置に依存するのを防ぎたい場合は、キーワード専用引
  数を使います。

* API では位置専用引数を使うと、将来引数名を変更しても互換性を保てます
  。


4.9.4. 任意引数リスト
---------------------

最後に、最も使うことの少ない選択肢として、関数が任意の個数の引数で呼び
出せるよう指定する方法があります。これらの引数はタプル (タプルとシーケ
ンス を参照) に格納されます。可変個の引数の前に、ゼロ個かそれ以上の通
常の引数があっても構いません。

   def write_multiple_items(file, separator, *args):
       file.write(separator.join(args))

通常このような *可変* 引数は、関数に渡される入力引数の残りを全て掬い取
るために、仮引数リストの最後に置かれます。 "*args" 引数の後にある仮引
数は 'キーワード専用' 引数で、位置引数ではなくキーワード引数としてのみ
使えることを意味します。

   >>> def concat(*args, sep="/"):
   ...     return sep.join(args)
   ...
   >>> concat("earth", "mars", "venus")
   'earth/mars/venus'
   >>> concat("earth", "mars", "venus", sep=".")
   'earth.mars.venus'


4.9.5. 引数リストのアンパック
-----------------------------

引数がすでにリストやタプルになっていて、個別な位置引数を要求する関数呼
び出しに渡すためにアンパックする必要がある場合には、逆の状況が起こりま
す。例えば、組み込み関数 "range()" は引数 *start* と *stop* を別に与え
る必要があります。個別に引数を与えることができない場合、関数呼び出しを
"*" 演算子を使って書き、リストやタプルから引数をアンパックします:

   >>> list(range(3, 6))            # 個別に引数を指定する通常の関数呼び出し
   [3, 4, 5]
   >>> args = [3, 6]
   >>> list(range(*args))            # 引数リストをアンパックして関数呼び出し
   [3, 4, 5]

同じやりかたで、"**" オペレータを使って辞書でもキーワード引数を渡すこ
とができます:

   >>> def parrot(voltage, state='a stiff', action='voom'):
   ...     print("-- This parrot wouldn't", action, end=' ')
   ...     print("if you put", voltage, "volts through it.", end=' ')
   ...     print("E's", state, "!")
   ...
   >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
   >>> parrot(**d)
   -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !


4.9.6. ラムダ式
---------------

キーワード "lambda" を使うと、名前のない小さな関数を生成できます。例え
ば "lambda a, b: a+b" は、二つの引数の和を返す関数です。ラムダ式の関数
は、関数オブジェクトが要求されている場所にならどこでも使うことができま
す。ラムダ式は、構文上単一の式に制限されています。意味付け的には、ラム
ダ形式は単に通常の関数定義に構文的な糖衣をかぶせたものに過ぎません。入
れ子構造になった関数定義と同様、ラムダ式もそれを取り囲むスコープから変
数を参照することができます:

   >>> def make_incrementor(n):
   ...     return lambda x: x + n
   ...
   >>> f = make_incrementor(42)
   >>> f(0)
   42
   >>> f(1)
   43

上記の例ではラムダ式を使って関数を返しています。  別の使い方としては、
小さな関数を引数として渡すこともできます。  たとえば、 "list.sort()"
はソートキー関数 *key* を受け取りますが、これにはラムダ関数を渡せます:

   >>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
   >>> pairs.sort(key=lambda pair: pair[1])
   >>> pairs
   [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]


4.9.7. ドキュメンテーション文字列
---------------------------------

ドキュメンテーション文字列については、その内容と書式に関する慣習をいく
つか挙げます。

最初の行には、オブジェクトの目的を短く簡潔にまとめます。 簡潔にするた
め、オブジェクトの名前や型は明記しないようにします。 これらは他の方法
で分かるためです (ただし、名前が関数の動作を表す動詞である場合は例外で
す)。 この行は大文字で始め、ピリオドで終えます。

ドキュメンテーション文字列中にさらに記述すべき行がある場合、二行目は空
行にし、まとめの行と残りの記述部分を視覚的に分離します。つづく行は一つ
またはそれ以上の段落で、対象物の呼び出し規約や副作用について記述します
。

複数行の文字列リテラルがモジュール、クラス、関数のドキュメンテーション
文字列として使われる場合、Python のパーサーはそのインデントを取り除き
ます。

以下に複数行のドキュメンテーション文字列の例を示します:

   >>> def my_function():
   ...     """なにもしないがドキュメントは書く。
   ...
   ...     本当になにもしない。
   ...
   ...         >>> my_function()
   ...         >>>
   ...     """
   ...     pass
   ...
   >>> print(my_function.__doc__)
   なにもしないがドキュメントは書く。

   本当になにもしない。

       >>> my_function()
       >>>


4.9.8. 関数のアノテーション
---------------------------

関数アノテーション はユーザ定義関数で使用される型についての完全にオプ
ションなメタデータ情報です (詳細は **PEP 3107** と **PEP 484** を参照
してください)。

*アノテーション* は関数の "__annotations__" 属性に辞書として格納され、
関数の他の部分には何も影響を与えません。パラメータアノテーションは、パ
ラメータ名の後にコロンを続けることによって定義され、その後にアノテーシ
ョンの値として評価される式が置かれます。戻り値アノテーションは、パラメ
ータリストと "def" 文の終わりを表すコロンの間に置かれたリテラル "->"
によって定義され、その後に式が続きます。次の例は必須の引数とオプション
引数、そして戻り値のアノテーションを持っています:

   >>> def f(ham: str, eggs: str = 'eggs') -> str:
   ...     print("Annotations:", f.__annotations__)
   ...     print("Arguments:", ham, eggs)
   ...     return ham + ' and ' + eggs
   ...
   >>> f('spam')
   Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
   Arguments: spam eggs
   'spam and eggs'


4.10. 間奏曲: コーディングスタイル
==================================

これから、より長く複雑な Python のコードを書くようになるので、ここで *
コーディングスタイル* について説明します。ほとんどの言語ではさまざまな
スタイルでコードを書けます (より正確には、コードを *整形* できます) が
、スタイルによって読みやすさは異なります。他の人が読みやすいコードを書
くことは常に大切で、よいコーディングスタイルを採用すると大いに役立ちま
す。

Python には、ほとんどのプロジェクトが守っているスタイルガイドとして
**PEP 8** があります。それは非常に読み易く目に優しいコーディングスタイ
ルを推奨しています。全ての Python 開発者はある時点でそれを読むべきです
。ここに最も重要な点を抜き出しておきます:

* インデントには空白 4 つを使い、タブは使わないこと。

  空白 4 つは (深くネストできる) 小さいインデントと (読み易い) 大きい
  インデントのちょうど中間に当たります。タブは混乱させるので、使わずに
  おくのが良いです。

* ソースコードの幅が 79 文字を越えないように行を折り返すこと。

  こうすることで小さいディスプレイを使っているユーザも読み易くなり、大
  きなディスプレイではソースコードファイルを並べることもできるようにな
  ります。

* 関数やクラスや関数内の大きめのコードブロックの区切りに空行を使うこと
  。

* 可能なら、コメントは行に独立で書くこと。

* docstring を使うこと。

* 演算子の前後とコンマの後には空白を入れ、括弧類のすぐ内側には空白を入
  れないこと: "a = f(1, 2) + g(3, 4)"。

* クラスや関数に一貫性のある名前を付けること。慣習では
  "UpperCamelCase" をクラス名に使い、 "lowercase_with_underscores" を
  関数名やメソッド名に使います。常に "self" をメソッドの第 1 引数の名
  前 (クラスやメソッドについては クラス初見 を見よ) として使うこと。

* あなたのコードを世界中で使ってもらうつもりなら、風変りなエンコーディ
  ングは使わないこと。どんな場合でも、Python のデフォルト UTF-8 または
  プレーン ASCII が最も上手くいきます。

* 同様に、ほんの少しでも他の言語を話す人がコードを読んだりメンテナンス
  する可能性があるのであれば、非 ASCII 文字も識別子に使うべきではあり
  ません。

-[ 脚注 ]-

[1] 実のところ、*オブジェクトへの参照渡し (call by object reference)*
    という言ったほうがより正確です。というのは、変更可能なオブジェクト
    が渡されると、呼び出された側の関数がオブジェクトに行った変更 (例え
    ばリストに挿入された要素) はすべて、関数の呼び出し側にも反映される
    からです。
