# 関数(かんすう, function)
###### tags: `Python`
Pythonの「関数」とは、数学の関数に似て、「何らかの値を渡すと、その値に応じた何らかの値を返すもの」といえる。
関数に渡す値(関数への入力値)のことを「引数」と呼ぶ。
関数を呼び出したときに得られる結果(関数からの出力)のことを「戻り値」とか「返り値」などという。
---
## 関数を作る理由とは
* コードがわかりやすくなる
各機能をまとめておくことで見やすくなるだけではなく、デバッグ作業も効率良くなります。
* 関数でコードの重複を減らすことができる。
同じような処理を複数の箇所でするときに、同じようなコードを何度も書くのではなく、一度書いたコードを使いまわすためです。
---

## 関数の作り方
```
def 関数名(引数1, 引数2, ..., 引数n):
処理文
return 戻り値
```
### 引数と戻り値が無い関数
```python=
def print_word():
print('Hello, World')
print_word() # print_word 関数を呼び出す
```
**Results:**
```
Hello, World
```
### 引数のある関数
```python=
def add(a, b):
print(a,' + ',b ,'= ', a+b)
add(7, 8) # add 関数を呼び出す
```
**Results:**
```
7 + 8 = 15
```
### 引数を指定する
キーワード付き引数を指定することができます。キーワード付き引数は関数定義側で、デフォルトの値を指定することができます。
```python=
def repeat_msg(msg, repeat = 3): # デフォルトの値を指定する
print(msg * repeat)
repeat_msg('Hello ')
repeat_msg('Happy ', repeat = 5)
```
**Results:**
```
Hello Hello Hello
Happy Happy Happy Happy Happy
```
### 戻り値のある関数
```python=
def re_add(a, b):
sum = a + b
return sum
a = int(input("a = "))
b = int(input("b = "))
print(a,' + ',b ,'= ', re_add(a, b)) # re_add 関数を呼び出す
```
**Results:**
```
a = 7
b = 9
7 + 9 = 16
```
### 関数のローカル性
関数内で数を置きかえる動作は、原則として、関数外の動作に影響を与えません。
```python=
a = 10
b = 7
def function(a):
b = a * 2
print('function b = ', b)
print('function end')
function(a)
print("main b = ", b)
```
**Results:**
```
function b = 20
function end
main b = 7
```
## 可変長引数
関数定義で引数に*と**(1個または2個のアスタリスク)をつけると、任意の数の引数(可変長引数)を指定することができる。
慣例として*args, **kwargsという名前が使われることが多いが、*と**が頭についていれば他の名前でも問題ない。
### *args
複数の引数をタプルとして受け取る。
```python=
def args_sum(*args):
print('args:', args, 'sum = ',sum(args))
args_sum(1, 10, 7, 9)
# sum = 27
args_sum(1, 1, 2, 4, 8, 16, 32, 64)
# sum = 128
```
**Results:**
```
args: (1, 10, 7, 9) sum = 27
args: (1, 1, 2, 4, 8, 16, 32, 64) sum = 128
```
#### 引数と組み合わせる
```python=
def func_args(a, b, *args):
print('a: ', a)
print('b: ', b)
print('args: ', args)
func_args('python', 10, 2, 'java', 77)
func_args(0, 'python')
```
**Results:**
```
a: python
b: 10
args: (2, 'java', 77)
a: 0
b: python
args: ()
```
#### *がついた引数を先に定義すること
この場合は*argsよりもうしろで定義された引数はキーワード形式引数名=値で指定する必要がある。
```python=
def func_args(a, *args, b):
print('a: ', a)
print('args: ', args)
print('b: ', b)
# func_args(0, 1, 1, 2, 4) TypeError
func_args(0, 1, 1, 2, b = 4)
```
**Results:**
```
a: 0
args: (1, 1, 2)
b: 4
```
### **kwargs
複数のキーワード引数を辞書として受け取る
```python=
def func_kwargs(**kwargs):
print('kwargs: ', kwargs)
func_kwargs(A = 1, B = 2, C = 3)
func_kwargs(Google = 'グーグル', Twitter = 'ツイッター', Amazon = 'アマゾン')
```
**Results:**
```
kwargs: {'A': 1, 'B': 2, 'C': 3}
kwargs: {'Google': 'グーグル', 'Twitter': 'ツイッター', 'Amazon': 'アマゾン'}
```
* #### キーワードを使ってキーワード引数を渡す
関数呼び出し時に辞書オブジェクトに**をつけて引数に指定することで、展開してそれぞれの引数として渡すことも可能。
```python=
def func_kwargs(Twitter, key, **kwargs):
print('Twitter: ', Twitter)
print('key: ', key)
print('kwargs: ', kwargs)
dict = {'Google': 'グーグル', 'Twitter': 'ツイッター', 'Amazon': 'アマゾン', 'key' : 1}
func_kwargs(**dict)
```
**Results:**
```
Twitter: ツイッター
key: 1
kwargs: {'Google': 'グーグル', 'Amazon': 'アマゾン'}
```
関数を呼び出す
```python=
print('python')
```
**Results:**
```
python
```
https://www.manabi-free.com/2019/06/11/%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0%e3%81%a7%e9%96%a2%e6%95%b0%e3%82%92%e4%bd%9c%e3%82%8b%e3%83%a1%e3%83%aa%e3%83%83%e3%83%88/