PHPerの為のPython入門 - 関数


前回の[超基礎編](http://qiita.com/odoku/items/97100c9fa20449b72588)からの続きで御座いますー。
今回は関数についての相違点と注意点をまとめてみます。


# 関数の定義

[超基礎編](http://qiita.com/odoku/items/97100c9fa20449b72588)でも説明しましたが、おさらいという事で。

まずはPHPのコード。

```php
<?php

function func() {
	echo 'hoge';
}

func();
```

こっちがPythonのコード。

```py
# coding=utf8

def func():  # 最後の : (コロン) を忘れずに！
	print('hoge')

func()
```

PHPでは`function`を使用しますが、Pythonでは`def`を使います。
Pythonはスコープの表現に`{}`は使用せず`インデント`を用います。


# 関数への値の渡し方 - その1

PHPもPythonも基本的な部分はそれほど変わりません。
ですが、Pythonの`関数`には`キーワード引数`と呼ばれる物があります。
例を上げて見てみましょう。

PHP使ってると、`デフォルト値を持っている引数`を大量に持つ`関数`に出くわす事があります。
そんで、最後の引数だけデフォルト値じゃない値にしたい場合とかは、以下の様に書かないといけません。

```php
<?php

function func($hoge='hoge', $piyo='piyo', $foo='foo', $bar='bar') {
	echo $hoge . PHP_EOL;
	echo $piyo . PHP_EOL;
	echo $foo . PHP_EOL;
	echo $bar . PHP_EOL;	
}

// 4つ目をデフォルト値以外にしたい場合、1〜3個目も書かないとダメ。
func('hoge', 'piyo', 'foo', 'fizz');
```

こういうケースで活躍するのが`キーワード引数`です！
PHPにはない特殊な書き方をする事で、指定した引数のみ渡すことが出来ます。

```py
# coding=utf8

def func(hoge='hoge', piyo='piyo', foo='foo', bar='bar'):
    print(hoge)
    print(piyo)
    print(foo)
    print(bar)

# 指定した所だけを渡せる！
func(bar='fizz')
```


# 可変長引数

## 通常の可変長引数

可変長引数を持つ関数を実装する場合、PHPでは以下の様になりますね。

```php
<?php

function func() {
	$args = func_get_args();
	var_dump($args);
}

func('hoge');
func('hoge', 'piyo');
```

これをPythonで表現するとこんな感じになるですよ！

```py
# coding=utf8

def func(*args):
	print(args)

func('hoge')
func('hoge', 'piyo')
```

引数の名前の先頭に`*`を付けるだけ。
`args`という引数名は固定ではなく、どんな名前でも大丈夫です。
`args変数`は`変更不可の配列（タプル）`として扱う事ができます。
とてもシンプルですねー。

## キーワード引数を可変長で扱う

さっき出てきた`キーワード引数`も可変長で受け取る事ができますよ。

```py
# coding=utf8

def func(**kwargs):
	print(kwargs)

func(hoge='hoge')
func(hoge='hoge', piyo='piyo')
```

`キーワード引数`の場合は引数の名前の先頭に`**`を付けるだけ。
この場合は`タプル`ではなく`引数名と値がペアの辞書`として扱うことが出来ます。

## 普通の引数もキーワード引数も可変長で扱う

さらに、これらを一緒に使うことも可能なのです！

```py
# coding=utf8

def func(*args, **kwargs):
	print(args)
	print(kwargs)

func('hoge')
func('hoge', piyo='piyo')
```


# 関数への値の渡し方 - その2

関数へ値を渡す際に`リスト（タプル）`や`辞書`を用いることが出来ます。

## 引数をリストで渡す

```py
# coding=utf8

def func(hoge, piyo):
	print(hoge)
	print(piyo)

args = ['foo', 'bar']

# 引数の順番とリストの順番が対応しているよ。
func(*args)
```

可変長引数の時と似ていますねー。
`リスト`が格納されている変数の名前に`*`を付けて関数に渡すことで、`リストの要素`を引数として扱う事が出来ます。

## 引数を辞書で渡す

```py
# coding=utf8

def func(hoge, piyo):
	print(hoge)
	print(piyo)

kwargs = {
	'hoge': 'foo',
	'piyo': 'bar',
}

func(**kwargs)
```

`リストで渡す方法`と同様に、`辞書`が格納されている変数の名前に`**`を付けて関数に渡すと、`キー(添字)`に対応した引数に値が代入されていきます。
ただし、存在しない引数名を`キー（添字）`に書くとエラーになるのでご注意を。。


# 引数のデフォルト値にリスト・辞書を指定してはいけない

僕がちょっとハマった部分を紹介しますよ。
まずはPHPのコードを見てくださいな。

```php
<?php

function func($hoge=array('foo')) {
	# hoge配列に 'bar' という要素を追加。
	$hoge[] = 'bar';
	var_dump($hoge);
}

func();
func();
```

`$hoge = array('foo')`に対して`'bar'`を追加して出力する関数を2回呼び出しています。
関数の実行結果はそれぞれ同じ結果になると思います。
これをPythonで書くと以下の様な感じ。

```py
# coding=utf8

def func(hoge=['foo']):
	# hogeリストに 'bar' という要素を追加。
	hoge.append('bar')
	print(hoge)

func()
func()
```

実はこのPythonのコードは **期待通りに動きません！！！！！**
実際に実行して見比べて見た方は、実行結果が違う事を確認出来たと思います。
詳しい説明は[他の人](http://qiita.com/yuku_t/items/fd517a4c3d13f6f3de40)に任せるとして、ここでは **引数のデフォルト値にはリスト・辞書は使っちゃダメ！**と覚えて下さい。


# まとめ

Pythonの関数は非常に柔軟でございます。
特に`キーワード引数`は強力なので、是非とも覚えてくださいませー。
次は[クラスについて説明](http://qiita.com/odoku/items/5a2ffac8b6c1be769f4c)するよ！