【初心者向け】JavaGoldが解説するPythonの基礎 パート2

##概要

[パート1](https://qiita.com/UpAllNight/items/dea9543741622a03bb13)に引き続きPythonの基礎的内容をシェアできればと思います！
ご覧になっていない方は、まずはパート1を＾＾


##アジェンダ
・if文
・for文
・関数
・例外処理
・pass文
・スコープ
・クラス
・クロージャ
・引数
・終わりに

##if文
Javaのswitch～case構文は存在しないが、「in」と言うキーワードを使うことで同じような実装が可能。「elif」は、「else if」の略。

・if文

```python

val1 = 1
val2 = 2

if val1 == val2:
  print('test1')
elif val1 > val2:
  print('test2')
else:
  print('test3') # test3
```

・「in」キーワードを使用した、switch文ライクな書き方

```python

val3 = 3

if val3 == 1:
  print('test1')
elif val3 in(2,3):
  print('test2') # test2
elif val3 in(3,4):
  print('test3')
else:
  print('test4')
```

##for文
for文は、Javaのforeach文に相当。range関数と組み合わせて使うことが多い。

・for文とrange関数

```python

for i in range(3):
  print(i) # 0、1、２と順に表示
```

・for文と文字列（リストや辞書なども使用可能）

```python

for c in 'test':
  print(c) # t, e, s, tと順に表示
```


ちなみに。。。
Pythonは、while文はあるが、do-while文は存在しない。

##関数
関数の定義には「def」を使用。※引数は全て~~参照渡し。~~値渡し。

```python

def fnc(a, b=1): # bはデフォルト値付きの引数
  return a + b # 戻り値

# 関数呼び出し
print(fnc(10)) # 11 
```

・関数を呼び出す際に、引数名を指定することで定義順を無視することが可能。

```python

def fnc(a, b, c):
  print(a, b, c)

# 関数呼び出し
fnc(c=3, a=1, b=2)# 1 2 3
```

■ 関数とメソッドの違い
ほとんど一緒の様なものと思って良いです!

**関数**：特定のクラスには縛られないもの。モジュール内にdefで定義されたもの。
クラス内のインスタンス化する前のdefで定義したものは関数。
書き方: 関数（ 引数 ）

**メソッド**：特定のクラス（またはそのクラスのインスタンス）専用のもの。~~クラス内にdefで定義されたもの。~~クラスがインスタンス化された後、関数がメソッドになる。
書き方: 値.メソッド（ 引数 ）

>例えば len("文 字 列") は "文 字 列" の長さを取得する関数なのに、 "文 字 列".split() は文字を空白文字で分割する メソッド (オブジェクト.関数) ですね。
基本的にはメソッドの場合は、そのオブジェクト固有の処理が多いです。
 例えば "文字列".split や "文字列".startswith などです。これは文字列固有です。
ですが len は文字列にも、リストにも使えます。 len("文字列") len([0, 1, 2]) なのです。こういった場合は、Pythonでは関数で用意されています。

>・Pythonの関数(オブジェクト) と オブジェクト.関数() の違いは何ですか？
>http://blog.pyq.jp/entry/2017/09/14/100000

※関数の全ての引数は参照渡しされるが、渡されたオブジェクトの型(mutable型とimmutable型)で挙動が異なる！
変更可能（mutable）な型では元の値は変更される。一方、変更不可（immutable）な型では元の値は変更されない。
変更不可（immutable）な型をもつオブジェクトが渡されたときは値渡し。

■変更不可（immutable）な型
・int, float, complexといった数値型
・文字列型（string）
・タプル型（tuple）
・bytes
・Frozen Set型

■変更可能（mutable）な型
・リスト型（list）
・バイト配列（bytearray）
・集合型（set）
・辞書型（dictionary）

##例外処理
「try~except~else~finally」という構文で処理。
exceptがJavaで言うcatch文で”例外が発生した時に実行する文、elseはexceptに補足されなかった処理を記述する。

```python

try:
  x = 10 / 0
except Exception as e:
  print(e) # division by zero
# 例外が発生しなかった場合に行う処理  
else:
  print('test1')
# 例外発生有無に関係なく必ず走る処理 
finally:
  print('test2')# test2
```

・明示的に例外を発生させるには「raise」を使用する。(Javaではthrow文)

```python
try:
  raise Exception('test3')
except Exception as e:
  print(e) # test3
```

##pass文
「何もしない」ことを明示するための構文。Javaにはない。

例えば、以下の様な時に使用する。
・条件分岐のときに何も実行しない
・例外が発生したときに何もしない
・関数やクラスの実装が明確でない

```python

# 偶数のみ出力
for i in range(10): 
if(i % 2) == 0:
  print(i)
else:
  pass
```

##スコープ
スコープの種類は以下の４種類。頭文字を取ってLEGB と言われている。

①ローカルスコープ(Local scope)
→関数内のみ。ローカルスコープからはビルトインスコープやモジュールスコープの変数や関数を参照することはできるが、変数に値を代入（上書き）することは不可。

②エンクロージング(Enclosing (function's) scope)
→関数の中で関数が定義されている、そんな場合に初めて意識するスコープで、端的にいうと関数の外側のローカルスコープ。

③グローバルスコープ(Global Scope)
→モジュール(ファイル全体)内全体。

④ビルトインスコープ(Built-in scope)
→組み込み変数(None)や組み込み関数(print関数)のスコープで、どこからでも参照可能。

スコープの詳細について[こちらの記事](http://note.crohaco.net/2017/python-scope/)を参考にさせて頂きました。
詳細が記載されていますので、時間がある方はご覧下さい。

##クラス
コンストラクタ(初期化メソッド)は「\_\_init\_\_」もしくは「＿_new\___」にし、第一引数には~~必ず「self」を定義する。~~selfにするのは慣例で、thisとか好きな名前にすることも可能。
selfは~~自身のインスタンスを表すオブジェクト。~~インスタンスを受け取る引数名

```python:Name.class

class Name:
  # クラス変数    
  LANG = 'JP'

  # コンストラクタ
  def __init__(self):
    self.name = ''

  # getter
  def getName(self):
    return self.name

  # setter
  def setName(self, name):
    self.name = name

taro = Name()
taro.setName('イチロー')
print(taro.getName()) # イチロー
print(Member.LANG) # JP
```

##クロージャ
関数のローカル変数を参照するような関数。
関数呼び出しが終わってもローカル変数を参照し続けられる。
Javascriptのクロージャとほぼ同等。

クロージャの詳細については[こちらの記事](https://qiita.com/naomi7325/items/57d141f2e56d644bdf5f)に載っています。

##引数

引数の種類は以下の４種類。

①通常の引数

②デフォルト値付きの引数
→関数呼び出しの際に省略された場合に採用するデフォルト値を定義した引数のこと。

```python
#②デフォルト値付きの引数
def fnc(a, b = 1):
  return a + b # 戻り値
```

③可変長の引数
→１つ以上の値を受け取る引数のこと。引数名の前にアスタリスク（*）を付ければこの引数になる。関数側では受け取った可変長引数はタプルとして扱う。

```python
#③可変長の引数
def fnc(a, b, *args):
  print(a, b, args)

fnc('a','b','c','d','e') # a b ('c','d','e')
```

④キーワード付きの可変長の引数
→引数を指定する際に、キーワードを付ける必要がある可変長の引数。
引数名の前にアスタリスク（*）を二つ付ければこの引数になる。なお、関数側では受け取った可変長引数は、定義時に付けた名前を持つ辞書型のデータとして扱う。

```python
#④キーワード付きの可変長の引数
def fnc(a, b, **args):
  print(a, b, args)

fnc('a','b',arg1 = 'c',arg2 = 'd',arg3 = 'e')# a b {'arg1': 'c', 'arg3': 'e', 'arg2': 'd'}
#fnc('a','b','c','d','e') ←キーワード指定しないとエラーになる
```

##終わりに
パート1 & 2でおおよそのPythonの基礎を説明しました。
PythonにはWEBフレームワークや、機械学習ライブラリが豊富にあるのでこの基礎と組み合わせればやりたいことは実現できる?はず！！
自分はこれからPythonを使ったWebAPIを作りたいと思います:raised_hand:

##参考文献
・Pythonの関数(オブジェクト) と オブジェクト.関数() の違いは何ですか？
http://blog.pyq.jp/entry/2017/09/14/100000

・Pythonのスコープについて
http://note.crohaco.net/2017/python-scope/

・【Python】クロージャ(関数閉方)とは
https://qiita.com/naomi7325/items/57d141f2e56d644bdf5f

・Pythonにおける値渡しと参照渡し
https://crimnut.hateblo.jp/entry/2018/09/05/070000

・AmadaShirou. Programing Keikensya No Tameno Python Saisoku Nyumon (Japanese Edition) Kindle 版