関数・クラス(1)

関数定義

Python で関数を定義するときには def を使う。

def 関数名(引数,[引数, ...]):
    定義
引数

Python の関数の引数は通常のもののほかに、デフォルト値付き、任意引数リスト、
キーワード引数がある。通常の引数は関数呼び出しで渡された値を順に受け取る。

def sum(a, b):
	print "%d+%d=%d"%(a,b,a+b)

sum(1, 2)
1+2=3

デフォルト値付き引数は、関数呼び出し時に省略可能で、その場合デフォルト値が使用される。
またデフォルト値付き引数は、関数呼び出し時に値の代入先引数を明示的に指定することができる。
代入先引数を明示的に指定する場合は、指定しないものより後ろにおく必要がある。
デフォルト値付き引数は、通常の引数より後ろにおく必要がある。

def func(a, b=0, c=1):
	print a, b, c

func(0, 1, 2)    # 普通に呼び出す
func(1)          # デフォルト値付き引数を省略
func(2, c=3)     # 値の代入先引数を明示的に指定

func(1, b=2, 3)  # こういう書き方は NG
0, 1, 2
1, 2, 1
2, 0, 3

任意引数リストは C の可変個引数関数のようなものだが python のリストとして
引数を受け取れるのでより扱いやすくなっている。
任意引数リストは引数の前に * (アスタリスク) をつけて宣言する。
任意引数リストは通常の引数とデフォルト値付き引数より後ろにおく必要がある。

def func(a, b=0, *c):
	print a, b,
	for x in c:
		print x,
	print ""

func(0)             # デフォルト値付き引数省略、任意引数リスト無し
func(0, 1)          # 任意引数リスト無し
func(0, b=2)        # 代入先を明示的に指定
func(0, 1, 2, 3)    # a, b に対応する引数より後ろは任意引数リストに入る。

func(0, b=1, 2, 3)  # こういう書き方はできない
0, 0
0, 1
0, 2
0, 1, 2, 3

キーワード引数は、辞書版任意引数リストといえるものである。
キーワード引数は引数の前に ** をつけて宣言する。
キーワード引数は通常の引数、デフォルト値付き引数、任意引数リストより後ろにおく必要がある。

func(a, b=0, *c, **d):
	print a, b,
	for x in c:
		print x,
	for k, v in d.items():
		print k, v,
	print ""

func(0)                     # 省略できる部分を全て省略
func(0, 1, 2, 3, x=4, y=5)  # 2, 3 が任意引数リストに、x=4, y=5 がキーワード引数の辞書に入る。

func(0, 1, 2, 3, x=4, 5)    # キーワード引数のあとに明示的な指定の無い引数は渡せない。
func(0, 1, 2, 3, a=4, b=5)  # 他の引数の名前になっているものはキーワードとして使用できない。
0, 0
0, 1, 2, 3, x, 4, y, 5
戻り値

Python の関数の戻り値はひとつだが、タプルを利用して複数の引数を返すような書き方もできる。

def func(a, b)
	return a+b, a-b, a*b, a/b

a, s, m, d = func(8, 3)
print a, s, m, d
11, 5, 24, 2

この場合、関数 func の return で、カンマで列挙された値がタプルとしてまとめられて
関数の戻り値となり、その戻り値は呼び出し側でカンマで列挙された変数に展開して代入される。

ジェネレータ

ジェネレータは関数と同様の形式で定義し、呼び出すことでイテレータを生成する。
具体的には、ジェネレータは内部で yield を使用している関数である。
yield は、関数の実行を一時中断して呼び出し元に値を返す。そして値が要求されたとき
続きから処理を再開する。

def add(numbers):
	sum = 0
	for x in numbers
		sum += x
		yield sum

for x in add([1,2,4,8,16]):
	print x
1
3
7
15
31