いまさらPython3（制御構造編）

# はじめに
自分用のPython3として基本的な制御構造を記載する。正確性より実用性を重視する。
（Javaや.NETを主に使ってる自分が、Pythonを使うためのページです）
Python公式HPのPythonチュートリアルを独自の解釈し記載。
https://docs.python.org/ja/3/tutorial/index.html

データ構造については、[いまさらPython3（データ構造編）へ](https://qiita.com/hos20r1/items/3326bdf6b4d2d75e33c0)

# 分岐
Pythonの分岐は、if文のみである。CやJavaと違いswitch文がない。

## if文
```
if 条件式１:
    …処理１…
elif 条件式２:
    …処理２…
else:
    …処理３…
```

## 条件式
###比較演算子
比較演算の優先順位は全て同じ (ブール演算より高い優先順位)

|演算子 |意味      |
|:-----|----------|
|<     |より小さい|
|<=    |以下      |
|>     |より大きい|
|>=    |以上      |
|==    |(値が)等しい    |
|!=    |(値が)等しくない|
|is    |オブジェクト(ID)が同一|
|is not|オブジェクト(ID)が異なる|
|in    |シーケンスに値が存在する|
|not in|シーケンスに値が存在しない|
- 比較演算子は連鎖可能（1<=a and a<=5は、1 <= a <= 5と書ける）
- シーケンスオブジェクトは、先頭から順に比較し等価の場合は再帰的に比較する

###ブール演算子
ブール演算を優先順位が高い順に、以下に記載

|演算子|意味        |
|:-----|------------|
|not x |否定        |
|and   |積(短絡評価)|
|or    |和(短絡評価)|

# 繰り返し
繰り返しは、for文とwhile文の２種類

## while文
```
while 条件式:
    …繰り返す処理…
else:
    …終了処理(breakで抜けたときは実行されない)…
```
```:whileの例
i = 0
while True:
    if i >= 5:
        break 
    i += 1
```
- ループ(for文を含む)では、breakでループブロックを終了する
- ループ(for文を含む)では、continueでループの残りを飛ばして次の反復を開始する
- Pythonでは、ループ(for文を含む)にelseブロックがあるのが特徴的

## for文
```
for 変数 in 反復可能オブジェクト:
    …反復処理…
else:
    …終了処理(breakで抜けたときは実行されない)…
```
```:forの例
for v in ['one', 'two', 'three']:
    print(v)
```
- 数値の数え上げはrange()を利用する  
  書式：range(終了値), range(開始値, 終了値, ステップ) *終了値は含まない  
  例：for i in range(10):   #例から、0から9まで数え上げる
- シーケンスと位置インデックスを合わせて使いたいときは、enumerate()を利用する  
  書式：enumerate(シーケンス)  
  例：for i, v in enumerate(['one', 'two', 'three']):  
- ２つ以上のシーケンスを同時にループを書けるときは、zip()を使う  
  書式：zip(シーケンス1, シーケンス2, ...)  
  例：for q, a in zip(['name', 'age', 'hight'], ['hos20rl', '100', '180']):

# ブロック
pythonの共通化・構造化する構造は、関数がベースである。
クラスはこの関数を最小限拡張して実装されるため、C++、Java、C#と比べて機能が弱い。

## 関数定義
```
def 関数名(仮引数名, 仮引数名, ...):
    ...処理...
    return 戻り値

値３ = 関数名(値１, 値２, ...)
```
```:関数の例
def func(a1, a2=10, a3=20):
    print("a1={} a2={} a3={}".format(a1, a2, a3))
    return a1 + a2 + a3

val = func(1, a3=5) 
print( "return={}".format(val))
```

- 関数の内部で関数が定義できる
- 引数の定義方法
    - デフォルト値の指定　書式：仮引数名=値
    - 位置引数のタプル化  
      書式：*仮引数名  
      例：def func(arg1, *args):  
      これより後ろの借り引数は、キーワード引数のみしか指定できない
    - キーワード引数の辞書化  
      書式：**引数名  
      例：def func(arg1, \*\*kwargs):
- 関数の呼び出し方法
    - タプル化引数の関数を呼び出すのは、位置引数と同じ
    - 辞書化引数の関数を呼び出すのは、キーワード引数と同じ
    - *演算子を使って関数をコールすると、シーケンスをアンパックして引数を渡せる　例：range(*args)

## クラス定義
```
class クラス名(基底クラス, 基底クラス, ...):
    def __init__(self, ...):
        …初期化処理…
    def メソッド名(self, 仮引数名, 仮引数名):
        …処理…

obj = クラス名()
```
```:クラスの例
class Bird:
    def __init__(self, cry):
        self.__cry = cry
    def sing(self):
        print("Bird<<" + self.__cry)

class Suzume(Bird):
    def __init__(self):
        super().__init__("チュンチュン")

class Rooster(Bird):
    def __init__(self):
        super().__init__("コケコッコー")

b1 = Suzume()
b2 = Rooster()
for b in [b1, b2]:
    b.sing()
```
- メソッドの第一仮引数は、クラスオブジェクトそのものが入る
- メンバ変数はメソッド内で値を代入することで利用開始できる（PythonではJavaやC#と違い変数宣言はない）
- メンバ変数はすべてパブリック(PythonにはJavaやC++などにあるアクセス修飾子がない)
- メンバ変数のスコープは、派生クラスと基底クラスともに同じスコープになる
- プライベートメンバは、先頭がアンダースコアにするのがPythonの慣例
- \_\_変数名(\*)は、\_classname\_\_変数名 に置き換えられる(プライベートメンバの名前の衝突を防ぐため)  
  (\*)2つ以上のアンダースコアを前置し、後置のアンダースコアが１つ以下のもの
- Pythonでは、クラス定義の外側でクラスの属性を後から追加・削除できる
  
# 例外処理
## try-except文
```
try:
    ...例外が発生する可能性のある処理...
except EOFError as ex:
    ...例外が発生したときの処理...
except:
    ...すべての例外をキャッチする...
else:
    ...例外が発生しなかった場合実行(例外が発生したときは通らない)...
finally:
    ...例外が発生しても発生しなくても実行...
    ...(リソースの開放処理を書くことが多い)...
```
```:例外処理の例
try:
    (val1, val2) = (5.0, 0.0)
    ans = val1 / val2
    print("{}/{}={}".format(ans, val1, val2))
except ZeroDivisionError as ex:
    print("ゼロで割っちゃだめですよ。")
finally:
    print("割り算を終わります。")
```
- ユーザ定義例外も生成できる  
  ユーザ定義例外は、Exceptionクラスを派生(直接または間接)してつくるべき
- 組み込み例外クラスは、下記のURLを参照  
  https://docs.python.org/ja/3/library/exceptions.html#exception-hierarchy

### raise文
raise文により例外の送出できる

```
raise 例外クラスのインスタンス
raise ←raiseの後ろに何もつけない場合、処理中の例外を再送出する
```
```:例外の送出の例
raise NameError('HiThere')
except NameError as ex:
    raise ex
except NameError:
    raise
```

### with文
with文は、オブジェクトの使用終了後にクリーンアップを実行させられるために利用する

```
with コンテキストマネージャ as コンテキストマネージャの名前, ...:
    ...処理...
```
```:with文の例
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")
```
- コンテキストマネージャは、\_\_enter\_\_() と \_\_exit\_\_() を持つクラスを定義する  
  \_\_enter\_\_()が初期化、\_\_exit\_\_()にクリーンアップ処理を定義

# 参考資料
## 演算子の優先順位
優先順位の高いものから順に記載

|演算子|説明|
|:-----|:---|
|(expressions...),<BR> [expressions...],<BR> {key: value...},<BR> {expressions...}|式結合またはタプル表示、<BR>リスト表示、<BR>辞書表示、<BR>集合表示|
|x[index],<BR> x[index:index],<BR> x(arguments...),<BR> x.attribute|添字指定、<BR>スライス操作、<BR>呼び出し、<BR>属性参照|
|await x|Await 式|
|**|べき乗|
|+x, -x, ~x|正数、負数、ビット反転|
|*, @, /, //, %|乗算、行列乗算、除算、切り捨て除算、剰余|
|+, -|加算および減算|
|<<, >>|ビットシフト|
|&|ビット演算(AND)|
|^|ビット演算(XOR)|
|&#124;|ビット演算(OR)|
|in, not in, is, is not, <, <=, >, >=, !=, ==|所属や同一性のテストを含む比較|
|not x|ブール演算(否定)|
|and|ブール演算(積)|
|or|ブール演算(和)|
|if -- else|条件式|
|lambda|ラムダ式|
|=|代入演算子|