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

先ほど説明のあった "while" 文に加えて、他の言語での経験から分かるよう
な通常のフロー制御文を少し工夫を効かせて使用します。


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" 文の代用となります。


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

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

   >>> # Measure some strings:
   ... words = ['cat', 'window', 'defenestrate']
   >>> for w in words:
   ...     print(w, len(w))
   ...
   cat 3
   window 6
   defenestrate 12

コレクションオブジェクトの値を反復処理をしているときに、そのコレクショ
ンオブジェクトを変更するコードは理解するのが面倒になり得ます。 そうす
るよりも、コレクションオブジェクトのコピーに対して反復処理をするか、新
しいコレクションオブジェクトを作成する方が通常は理解しやすいです:

   # Strategy:  Iterate over a copy
   for user, status in users.copy().items():
       if status == 'inactive':
           del users[user]

   # Strategy:  Create a new collection
   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()" が返すオブジェクトは、いろいろな点でリストであるかのように振
る舞いますが、本当はリストではありません。これは、イテレートした時に望
んだ数列の連続した要素を返すオブジェクトです。しかし実際にリストを作る
わけではないので、スペースの節約になります。

このようなオブジェクトは *イテラブル (iterable)* と呼ばれます。 これら
は関数や構成物のターゲットとして、あるだけの項目を逐次与えるのに適して
います。 "for" 文がそのような構成物であることはすでに見てきており、イ
テラブルを受け取る関数の例には "sum()" があります:

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

この後には、イテラブルを返したりイテラブルを引数で受け取るいくつかの関
数が出てきます。 データ構造 では、 "list()" についてより詳しく説明しま
す。


4.4. "break" 文と "continue" 文とループの "else" 節
===================================================

"break" 文は、C 言語と同じく、最も内側の "for" または "while" ループを
中断します。

ループ文は "else" 節を持つことができます。これは、 ("for" で) イテラブ
ルを使い切ってループが終了したとき、または ("while" で) 条件が偽になっ
たときに実行されますが、 "break" 文でループが終了したときは実行されま
せん。この動作を、素数を探す下記のループを例にとって示します:

   >>> for n in range(2, 10):
   ...     for x in range(2, n):
   ...         if n % x == 0:
   ...             print(n, 'equals', x, '*', n//x)
   ...             break
   ...     else:
   ...         # loop fell through without finding a factor
   ...         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" 文の "else" よりも "try" 文の "else" に似
ています。 "try" 文の "else" 句は例外が発生しなかった時に実行され、ル
ープの "else" 句は "break" されなかった場合に実行されます。 "try" 文と
例外についての詳細は 例外を処理する を参照してください。

"continue" 文も C 言語から借りてきたもので、ループの次のイテレーション
を実行します:

   >>> for num in range(2, 10):
   ...     if num % 2 == 0:
   ...         print("Found an even number", num)
   ...         continue
   ...     print("Found an odd number", num)
   ...
   Found an even number 2
   Found an odd number 3
   Found an even number 4
   Found an odd number 5
   Found an even number 6
   Found an odd number 7
   Found an even number 8
   Found an odd number 9


4.5. "pass" 文
==============

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

   >>> while True:
   ...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
   ...

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

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

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

   >>> def initlog(*args):
   ...     pass   # Remember to implement this!
   ...


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

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

   >>> def fib(n):    # write Fibonacci series up to n
   ...     """Print a Fibonacci series up to n."""
   ...     a, b = 0, 1
   ...     while a < n:
   ...         print(a, end=' ')
   ...         a, b = b, a+b
   ...     print()
   ...
   >>> # Now call the function we just defined:
   ... 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):  # return Fibonacci series up to n
   ...     """Return a list containing the Fibonacci series up to n."""
   ...     result = []
   ...     a, b = 0, 1
   ...     while a < n:
   ...         result.append(a)    # see below
   ...         a, b = b, a+b
   ...     return result
   ...
   >>> f100 = fib2(100)    # call it
   >>> f100                # write the result
   [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.7. 関数定義についてもう少し
=============================

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


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

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

   def ask_ok(prompt, retries=4, reminder='Please try again!'):
       while True:
           ok = input(prompt)
           if ok in ('y', 'ye', 'yes'):
               return True
           if ok in ('n', 'no', 'nop', 'nope'):
               return False
           retries = retries - 1
           if retries < 0:
               raise ValueError('invalid user response')
           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.7.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, "!")

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

   parrot(1000)                                          # 1 positional argument
   parrot(voltage=1000)                                  # 1 keyword argument
   parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
   parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
   parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
   parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

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

   parrot()                     # required argument missing
   parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
   parrot(110, voltage=220)     # duplicate value for the same argument
   parrot(actor='John Cleese')  # unknown keyword argument

関数の呼び出しにおいて、キーワード引数は位置引数の後でなければなりませ
ん。渡されるキーワード引数は全て、関数で受け付けられる引数のいずれかに
対応していなければならず (例えば、"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
を参照) を受け取ります。 "**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.7.3. 特殊なパラメータ
-----------------------

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

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

   def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
         -----------    ----------     ----------
           |             |                  |
           |        Positional or keyword   |
           |                                - Keyword only
            -- Positional only

ここで、"/" と "*" はオプションです。使用された場合、これらの記号は、
引数が関数に渡される方法、すなわち、位置専用、位置またはキーワード、キ
ーワード専用、といった引数の種類を示します。キーワード引数は、名前付き
引数とも呼ばれます。


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

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


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

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

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


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

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


4.7.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_args" は、関数定義に "*" があるので、引数はキー
ワード専用になります:

   >>> 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.7.3.5. 要約
~~~~~~~~~~~~~

使用例で、関数定義でどの種類の引数を使うかべきかがわかると思います:

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

ガイドとしては、

* もし引数の名前をユーザーに知らせる必要がないなら、位置専用引数を使用
  しましょう。これは引数の名前がユーザーにとって意味がなく、関数が呼ば
  れたときの引数の順序が問題であり、または、位置引数と任意のキーワード
  を使用する必要がある場合に便利です。

* 引数の名前に意味があり、それにより関数の定義がより明らかになる、また
  は、ユーザーが引数の順番に縛られることを避けたほうがいいと考えるのな
  ら、キーワード専用引数を使用しましょう。

* APIの場合、将来引数の名前が変更された場合にAPIの変更ができなくなるこ
  とを防ぐために、位置専用引数を使用しましょう。


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

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

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

Normally, these *variadic* arguments will be last in the list of
formal parameters, because they scoop up all remaining input arguments
that are passed to the function. Any formal parameters which occur
after the "*args" parameter are 'keyword-only' arguments, meaning that
they can only be used as keywords rather than positional arguments.

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


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

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

   >>> list(range(3, 6))            # normal call with separate arguments
   [3, 4, 5]
   >>> args = [3, 6]
   >>> list(range(*args))            # call with arguments unpacked from a list
   [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.7.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

上記の例は、関数を返すところでラムダ式を使っています。もう1つの例では
、ちょっとした関数を引数として渡すのに使っています:

   >>> 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.7.7. ドキュメンテーション文字列
---------------------------------

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

最初の行は、常に対象物の目的を短く簡潔にまとめたものでなくてはなりませ
ん。簡潔に書くために、対象物の名前や型を明示する必要はありません。名前
や型は他の方法でも得られるからです (名前がたまたま関数の演算内容を記述
する動詞である場合は例外です)。最初の行は大文字で始まり、ピリオドで終
わっていなければなりません。

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

Python のパーザは複数行にわたる Python 文字列リテラルからインデントを
剥ぎ取らないので、ドキュメントを処理するツールでは必要に応じてインデン
トを剥ぎ取らなければなりません。この処理は以下の規約に従って行います。
最初の行の *後にある* 空行でない最初の行が、ドキュメント全体のインデン
トの量を決めます。(最初の行は通常、文字列を開始するクオートに隣り合っ
ているので、インデントが文字列リテラル中に現れないためです。) このイン
デント量と "等価な" 空白が、文字列のすべての行頭から剥ぎ取られます。イ
ンデントの量が少ない行を書いてはならないのですが、もしそういう行がある
と、先頭の空白すべてが剥ぎ取られます。インデントの空白の大きさが等しい
かどうかは、タブ文字を (通常は 8 文字のスペースとして) 展開した後に調
べられます。

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

   >>> def my_function():
   ...     """Do nothing, but document it.
   ...
   ...     No, really, it doesn't do anything.
   ...     """
   ...     pass
   ...
   >>> print(my_function.__doc__)
   Do nothing, but document it.

       No, really, it doesn't do anything.


4.7.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.8. 間奏曲: コーディングスタイル
=================================

これからより長くより複雑な 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)* と
    書けばよいのかもしれません。というのは、変更可能なオブジェクトが渡
    されると、関数の呼び出し側は、呼び出された側の関数がオブジェクトに
    行ったどんな変更 (例えばリストに挿入された要素) にも出くわすことに
    なるからです。
