Pythonに登場する文を階層的にまとめてみた！

# この記事を書くきっかけ
Pythonでプログラミングの問題を解くことが日課になっています。毎日コードを書いていますが、たまに何を書いているのかよくわからなくなります。for文とwhile文の使い分けがあやしかったり、新しい〇〇文の登場に面食らったり。そんなときは頭がもやもやします。


そもそも「〇〇文」ってたくさんあるけど、どういうジャンル分けなんだろう、と疑問に思ったので記事にしてまとめてみました。

大まかに「文」の種類を知っていれば、「〇〇文って△△文の一種だよね」と分類分けすることができて、新しく知る「〇〇文」に対しても、既知の「文」に対しても、理解が深まるはずです。

すべての「文」を扱っているわけではありませんが、よく見かけるPythonに登場する文を階層的にまとめてみたので、私のような初学者の方はぜひ参考にしてみてください。

# 文
コンピュータに対して、処理の指示をする命令を、「命令文（ステートメント）」または単純に「文」と言います。文は予約語、演算子、識別子などを組み合わせて作ります。
```
文
├─ 実行文
│  ├─ 代入文
│  │  ├─ 単純代入文
│  │  └─ 複合代入文
│  ├─ 制御文
│  │  ├─ 繰り返し文
│  │  │  ├─ for文
│  │  │  └─ while文
│  │  └─ 判断/分岐文
│  │     ├─ if文
│  │     ├─ if else文
│  │     └─ elif文
│  ├─ ジャンプ文
│  │  ├─ break文
│  │  ├─ continue文
│  │  └─ return文
│  └─ その他
│     ├─ import文
│     ├─ del文
│     ├─ pass文
│     ├─ with文
│     ├─ try文
│     ├─ assert文
│     └─ yield文
└─ 宣言文
   ├─ グローバル宣言
   ├─ 関数の宣言（定義）
   └─ クラスの宣言（定義）

```

## 実行文
実行文とは、Pythonプログラムの実行時に直接的な操作を行う文を指します。値の代入、制御フローの変更、関数の呼び出し、ループの実行などが含まれます。実行文は、プログラムの動作を**直接**制御する役割を持ちます。
### 代入文
代入文とは、変数に値を割り当てるための文です。Pythonでは、代入文を使用して変数に値を格納し、その後のプログラムでその値を使用できます。
代入文には、単純代入文と複合代入文（累算代入文）の2種類があります。

#### 単純代入文
単純代入文は、右辺の値を左辺の変数に割り当てます。
```python
x = 5
name = "Qiita"
active = True
```
#### 複合代入文
複合代入文は、代入と演算を同時に行います。これにより、変数の値を更新できます。
```python
x += 1  # x = x + 1
x -= 2  # x = x - 2
x *= 3  # x = x * 3
x /= 4  # x = x / 4
x %= 5  # x = x % 5
```

変数の初期化を行う場合、以下のような書き方も可能です。
```python
# 複数の変数に一括代入
a, b, c = 1, 2, 3
print(a, b, c)  # 出力: 1 2 3

# 同じ値を複数の変数に代入
a = b = c = 0
print(a, b, c)  # 出力: 0 0 0
```
複数の変数に同じ値を一度に代入する方法は「連鎖代入」と呼ばれます（例：a = b = c = 0）。複数の変数を同じ初期値で初期化したい場合に便利ですが、使い方には注意が必要です。
### 制御文
制御文（Control Statement）とは、プログラム実行の流れを制御するための文です。制御文を使うことで、条件に応じて異なるコードを実行したり、特定のコードブロックを繰り返し実行したりすることができます。
#### 繰り返し文（ループ文）
##### for文
for文は、指定された回数や要素の数だけ繰り返し処理を行うための文です。反復回数や要素数が明確にわかっている場合に便利です。

主に以下の2つの方法で使用されます。
1. 指定された範囲の数値に対して繰り返す
1. シーケンスの各要素に対して繰り返す
シーケンスとは、繰り返し処理する対象となるオブジェクト（リスト、タプル、文字列、辞書など）を指します。
```python
for 変数 in イテラブル:
    # 繰り返すブロック

# 指定された範囲の数値に対して繰り返す
for i in range(10):
    print(i)
    
# シーケンスの各要素に対して繰り返す
fruit = ["apple", "banana", "cherry"]
for f in fruit:
    print(f)
```
##### while文
while文は繰り返し回数があらかじめ定まらない繰り返しです。「何回繰り返すかわからないが、条件式を満たしている間は繰り返す」という処理を行います。
```python
while 条件:
    # 条件が真である間繰り返し実行されるコード
    
i = 0  # カウンター変数の初期化
while i < 5:  # 条件
    print(i)  
    i += 1    # i をインクリメント（1 増やす）
```
#### 判断/分岐文
##### if文
if文は、条件が真である場合に特定のコードブロックを実行したいときに使用します。条件が偽の場合は、そのコードブロックはスキップされます。
```python
x = 10
if x > 0:
    print("xは正の数です")
```
##### if else文
if-else文は、条件が真の場合に特定のコードブロックを実行し、条件が偽の場合に別のコードブロックを実行したいときに使用します。
```python
x = -5
if x > 0:
    print("xは正の数です")
else:
    print("xは0以下です")
```
##### elif文
elif（else if）文は、複数の条件を順に評価し、最初に真となる条件のコードブロックを実行したいときに使用します。elif文は複数指定できます。
```python
x = 0
if x > 0:
    print("xは正の数です")
elif x == 0:
    print("xは0です")
else:
    print("xは負の数です")
```

### ジャンプ文
ジャンプ文とは、プログラムの実行フローを変更するために使用される文です。
#### break文
break文は、ループを途中で終了させたい場合に使用します。特定の条件が満たされたときにループから抜け出します。
```python
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num == 3:
        break
    print(num)
# 出力:
# 1
# 2
```
#### continue文
continue文は、ループの現在の反復をスキップして次の反復に進みたい場合に使用します。特定の条件が満たされたときに残りのコードをスキップして次のループに移ります。
```python
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        continue
    print(num)
# 出力:
# 1
# 3
# 5   
```
#### return文
return文は、関数の実行を終了し、関数から値を返すために使用します。関数内で特定の条件が満たされたときに値を返して関数を終了します。
```python
def check_number(x):
    if x > 0:
        return "正の数"
    elif x < 0:
        return "負の数"
    else:
        return "0"

print(check_number(10))  # 出力: 正の数
print(check_number(-5))  # 出力: 負の数
print(check_number(0))   # 出力: 0
```
関数の呼び出し元に「式」の値を持って戻ってくるイメージです。

### その他
#### import文
import文は、Pythonプログラムで他のモジュール（Pythonファイルやライブラリ）をインポートして使用するための文です。import文を使用することで、他のファイルやライブラリの機能を再利用できます。

- モジュール全体をインポートする場合: `import モジュール名`
- モジュール内の特定の要素をインポートする場合: `from モジュール名 import 要素名`
- モジュールに別名を付けてインポートする場合: `import モジュール名 as 別名`
- 複数の要素をインポートする場合: `from モジュール名 import 要素1, 要素2`

```python
import math

print(math.sqrt(16))  # 出力: 4.0
```
```python
from math import sqrt

print(sqrt(16))  # 出力: 4.0
```
```python
import numpy as np

array = np.array([1, 2, 3, 4])
print(array)
```
```python
from math import sqrt, pi

print(sqrt(16))  # 出力: 4.0
print(pi)        # 出力: 3.141592653589793
```
#### del文
del文は、変数やリストの要素、辞書のキーなどを削除するために使用されます。
```python
# リストの要素の削除
my_list = [1, 2, 3, 4]
del my_list[2]
print(my_list)  # 出力: [1, 2, 4]

# 辞書のキーの削除
my_dict = {'a': 1, 'b': 2, 'c': 3}
del my_dict['b']
print(my_dict)  # 出力: {'a': 1, 'c': 3}
```
#### pass文
pass文は、何もしない文です。空のコードブロックを作成する際に使用されます。
```python
def my_function():
    pass  # 何もしない
```
#### with文
with文は、リソースの準備と後片付けを自動で行う構文です。主にファイル操作やデータベース接続などのリソースの管理（ファイルのオープン/クローズなど）を自動的に行います。

**もっとわかりやすく！**
ファイルを開いて書き込みをする場合
1. 準備: ファイルを開く
2. 操作: ファイルに書き込む
3. 片付け: ファイルを閉じる

この３つの操作を必要とします。with文を使うと、この「準備」と「片付け」を自動でやってくれます。
```python
with open('example.txt', 'w') as file:
    file.write('Hello, world!')
```
1. 準備: open('example.txt', 'w')が実行されてファイルが開きます。
2. 操作: file.write('Hello, world!')でファイルに書き込みます。
3. 片付け: withブロックを抜けると、自動的にファイルが閉じます。

**もっと詳しい説明**
`with open('example.txt', 'w') as file:`
open関数を使ってファイルexample.txtを開きます。ファイルが書き込みモード（'w'）で開かれ、fileという変数にファイルオブジェクトが代入されます。
with文を使うことで、ファイルが自動的に管理され、withブロックを抜けるとファイルが自動的に閉じられます。

`file.write('Hello, world!')`
fileオブジェクトのwriteメソッドを使って、ファイルに文字列'Hello, world!'を書き込みます。

#### try文
try文は、例外処理を行うために使用されます。エラーが発生する可能性のあるコードを実行し、エラーが発生した場合の処理を指定します。

exceptには、エラーの種類（ValueError,TypeErrorなど）を指定します。exceptは複数指定できます。finallyには、例外処理の「後始末」を指定します。elseに、例外が発生しなかった場合の処理を書くこともできます。
```python
try:
    # エラーが発生する可能性のあるコード
    x = 10 / 0
except ZeroDivisionError:
    # ZeroDivisionErrorが発生した場合の処理
    print("ゼロによる除算は許可されていません")
except Exception as e:
    # その他のすべての例外に対する処理
    print(f"予期しないエラーが発生しました: {e}")
else:
    # エラーが発生しなかった場合の処理
    print("正常に処理が完了しました")
finally:
    # エラーの有無にかかわらず、必ず実行される処理
    print("このブロックは常に実行されます")
```
#### assert文
assert文は、条件が真であることを確認するために使用されます。条件が偽の場合、AssertionErrorが発生します。assert文は主にデバッグやテストコード内で使用され、プログラムの前提条件を明確にするのに役立ちます。

assertは、英語で「断言する、明言する」という意味があります。

`構文: assert 条件, [エラーメッセージ(オプション)]`
```python
x = 5
assert x > 0, "xは正の数でなければなりません"
assert x < 0, "xは負の数でなければなりません"  # ここでAssertionErrorが発生します
```
**assert文の利点**
1. デバッグの補助
assert文を使うことで、プログラムの重要な前提条件が満たされているかどうかを簡単にチェックできます。これにより、プログラムのロジックエラーを早期に発見できます。
2. コードのドキュメント化
assert文は、コードの前提条件や期待される状態を明示的に示すため、コードの意図を他の開発者に伝える手助けとなります。
3. テストの強化
テストコード内でassert文を使用することで、テスト対象の関数やメソッドが正しい動作をしているかどうかを確認できます。

**注意点**
assert文は主にデバッグやテストのためのものであり、実行時のエラーハンドリングにはtry-except文を使用します。assert文は、最適化モード（-Oオプション）でスクリプトを実行すると無視されるため、エラーハンドリングの目的には適しません。

#### yield文
yield文は、Pythonでジェネレータを作成するために使用されます。ジェネレータは、イテレータの一種であり、通常の関数と似ていますが、一度に一つの値を生成し、その値を返し、次の呼び出し時には前回の状態から処理を再開します。メモリ効率が良く、大きなデータセットを扱う際に適しています。

yieldは英語で「産出する、生み出す」という意味があります。ジェネレーターの「要素が要求される場面でその都度データを産出する」という動きがyieldという言葉に表れています。
```python
def generate_numbers():
    yield 1
    yield 2
    yield 3

# ジェネレータを作成
gen = generate_numbers()

# ジェネレータから値を取得
print(next(gen))  # 出力: 1
print(next(gen))  # 出力: 2
print(next(gen))  # 出力: 3
# print(next(gen))  # StopIterationが発生します
```
## 宣言文
宣言文とは、プログラムにおいて変数、関数、クラスなどの名前を宣言し、それらに特定の値や挙動を割り当てる文です。
### グローバル宣言
グローバル宣言は、関数やメソッドの内部でグローバル変数を使用するために使います。Pythonでは、関数内で変数を直接使用すると、その変数はローカル変数と見なされます。「global」を使うことで、関数内部からでもグローバル変数を参照したり変更したりすることができます。
```python
x = 10  # グローバル変数

def modify_global():
    global x  # グローバル変数xを使用することを宣言
    x = 20    # グローバル変数xを変更

modify_global()
print(x)  # 出力: 20
```
### 関数の宣言（定義）
関数の宣言は、特定の処理を実行する一連の文を定義します。関数を定義することで、再利用可能なコードブロックを作成できます。関数は「def」を使って定義します。
```python
def greet(name):
    return f"Hello, {name}!"

print(greet("Qiita"))  # 出力: Hello, Qiita!
```
### クラスの宣言（定義）
クラスの宣言は、オブジェクト指向プログラミングの基本構成要素であり、オブジェクトの属性（データ）とメソッド（関数）を定義します。クラスを使うことで、データと機能をひとまとめにして扱うことができます。クラスは「class」を使って定義します。

```python
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"私の名前は{self.name}です。{self.age}歳です。")

# クラスのインスタンス化とメソッドの呼び出し
student = Student("太郎",15)
student.introduce()  # 出力: 私の名前は太郎です。15歳です。
```

# まとめ
Pythonでよく見かける文をまとめてみました。Pythonにはいろいろな種類の文がありますが、分類分けをすることでPythonの「命令文」への解像度が上がりました。with文やassert文、yield文は今回はじめて知ったので、それも勉強になりました。

「今、自分はどんな文を書きたいのか」、「何をパソコンに命令したいのか」という視点を忘れずに、スマートにコーディングできるようになりたいですね。