Python の超基本

# Python とは？
Pythonは、Perl から派生した汎用のプログラミング言語であり、1991年にGuido van Rossumによって設計されました。

Python は、シンプルで読みやすい構文を特徴とし、豊富な標準ライブラリやサードパーティのツール、フレームワークが提供されています。

# Python の特徴
Python は人間が理解しやすいソースコードのままプログラムとして配布し、**インタプリタ**と呼ばれるプログラムが1行ずつ解釈しながら実行する「**インタプリタ方式**」を採用しています。
インタプリタ方式を採用することで、ソースコードを手軽に修正や変更しやすいメリットがあります。

そのため、Pythonはコードの記述が容易であり、実行も比較的迅速です。
例えば「Hello!」を表示させたい場合、C 言語では以下のように4行書く必要がありますが、
```c:C言語
#include <stdio.h>

int main() {
    printf("Hello!\n");
    return 0;
}
```

Python ではたった1行だけのみの構成となります。
```python:Python
print('Hello!')
```

また、Pythonは「**オブジェクト指向言語**」の1つであり、オブジェクト指向開発という「データと処理」を1セットとしてプログラムを組み立てていく開発手法に適した言語の一つです。
オブジェクト指向言語には、Python の他にもJava、C#、Ruby、PHP などがあります。
![スクリーンショット 2024-03-19 11.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/ff23ac7a-ba8b-fa34-09ff-b51e000f2415.png)

Python はWeb開発、データ解析、機械学習、人工知能、自然言語処理など、様々な分野で広く利用されており、ここ最近人気が高まっている言語の一つです。

# プログラムの基本構造
Python などのプログラム言語を使用して開発する際には、インターネットサービス、人工知能、スマートフォンアプリ、ゲームなど、多岐にわたるプロジェクトを実現できます。
これらのプロジェクトは複雑な動作をするように思われるかもしれませんが、プログラムは基本的に以下の3つの構造で構成されています。

 + **順次進行**
 + **条件分岐**
 + **繰り返し**

これらの基本構造は「**プログラムの制御構造**」または「**制御フロー**」と呼ばれ、複雑なプログラムの構築に欠かせません。
この3つの構造は、どのプログラミング言語でも共通しています。

## 順次進行
順次進行は、プログラムが記述されている上から順に処理を実行するプログラム構造です。
これはプログラムの基本的な動作であり、ソースコードが上から順に処理A、処理B、処理Cと記述されていれば、それらの処理は上から順にA、B、Cと実行されます。
![スクリーンショット 2024-03-19 13.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/87de81f7-9091-2875-6557-7968d9350a71.png)

例えば、ソースコードが「おはよう」「こんにちは」「こんばんは」とパソコンの画面上に表示されるプログラムだったとします。
プログラムを実行すると、上から順に「おはよう」「こんにちは」「こんばんは」と表示されます。
```python
print("おはよう")
print("こんにちは")
print("こんばんは")
```
```:実行結果
おはよう
こんにちは
こんばんは
```

## 条件分岐
条件分岐とは、特定の条件のときはAという処理、そうではないときにBという処理をするプログラム構造です。
![スクリーンショット 2024-03-19 13.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/1f2c84ce-eb9d-9b6a-7c68-287c0c10ae2b.png)

例えば、あるデータの値が20以上なら「おとな」と画面上に表示させて、
![スクリーンショット 2024-03-19 13.34.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/8e5c1976-3dd1-205b-91e3-fdc82be1bb07.png)

20未満なら「こども」と表示させるといった処理ができます。

以下は Python での実行例で、この場合「こども」と表示されます。
```python
data = 15

if data >= 20:
    print("おとな")
else:
    print("こども")
```
```:実行結果
こども
```

ちなみに条件分岐を行う場合は、if 文、else 文、elsif 文等を使用します。

## 繰り返し
繰り返しとは、決まった回数や条件を満たすまで同じ処理を繰り返すプログラム構造です。
繰り返しは、反復処理と言ったりもします。
![スクリーンショット 2024-03-19 13.44.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/54c4fc11-f53b-0db1-34d0-fa4ac3e65345.png)

例えば、「こども」という文字を繰り返し20回表示させたい場合に使います。
![スクリーンショット 2024-03-19 14.11.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/e40a0c9a-7d75-b774-a865-9a9da53ac7c7.png)

他にも、あるデータに1ずつ足していき、そのデータが20未満であれば「こども」と表示させ、
20以上になったら、繰り返し処理を終わらせるということもできます。
![スクリーンショット 2024-03-19 14.14.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/37bec379-4d89-0e83-0102-a8788a44d692.png)

その場合の Python の実行例です。
```python
data = 0

while data < 20:
    print("こども")
    data += 1
```
```:実行結果
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
こども
```

# 変数
Python を含むプログラミング言語では、「**変数**」を使ってデータを一時的に保存し、後で参照や操作を行うことができます。
変数はデータに名前をつけるための名札のようなものであり、ソースコード内で変数を使用することで、その中身を表示させることができます。
![スクリーンショット 2024-03-19 14.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/cb737ae4-16c2-3fe6-ceec-0b92c406d9e8.png)

変数を作ることを「**変数を宣言する**」と言います。
初めて変数にデータを入れることを「**変数の初期化**」と言います。
![スクリーンショット 2024-03-19 14.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/4d124f92-1063-6a69-784a-a785bcf606ca.png)

変数に名前を付ける「**変数名**」には以下の文字を使用することができます。
 + **アルファベット**
 + **数字**
 + **_(アンダースコア)**

変数名を決める際には以下のルールがあります。
 + **数字から始めることは不可**
 + **大文字と小文字は区別される**
 + **以下の予約語(既に役割が決まっている単語)は変数名にすることはできない**
     + return
     + class
     + for
     + while ...

# データ型
「**データ型**」とは、データ（値やオブジェクト）の型です。
![スクリーンショット 2024-03-19 19.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/640fac53-ba40-342c-aca3-fb40a67efc80.png)

データ型には以下の種類があります。
+ **数値型**
    + int 型(整数)
    + float 型(少数)
+ **文字列型(string 型)**
+ **ブール型(boolean 型)**

この中でブール型について、`True` または `False` の2つのうち、どちらか1つを持つ型です。
以下のコードを例にすると、`a`は`b`よりも値が大きいので、実行時は`True`が表示されます。
```python
a = 10
b = 1

bool01 = (a > b)

print(bool01)
```
```:実行結果
True
```

反対に`a`は`b`よりも値が小さいので、実行時は`False`と表示されます。
```python
a = 1
b = 10

bool01 = (a > b)

print(bool01)
```
```:実行結果
False
```

変数が保持しているデータ型を確認する場合には、「**type 関数**」を使用します。
以下の例の場合、`print(type(bool01))`は、変数`bool01`からデータを取り出して`type`関数に渡し、`type`関数はデータから型情報を取得して返し、その型情報を`print`関数に渡して表示します。
```python
a = 10
b = 1

bool01 = (a > b)

print(bool01)
print(type(bool01))
```
```:実行結果
True
<class 'bool'>
```

Python は「**動的型付け言語**」に分類され、変数を宣言する際にデータ型を指定する必要はありません。
Python が自動的にデータを判断してくれるからです。
動的型付け言語は Python 以外にも、Ruby、JavaScript、PHP などがあります。
![スクリーンショット 2024-03-19 19.40.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/8e6b568b-8a10-b1f6-2aaf-77e361cb3f04.png)

ちなみに C 言語の場合、変数を宣言する際には必ずその変数のデータ型を指定する必要があります。
C 言語は「**静的型付け言語**」として知られ、変数のデータ型がコンパイル時に決定されます。
このため、変数のデータ型を宣言しないとコンパイルエラーが発生します。

C言語の場合、変数の宣言は次のように行います。
```c
#include <stdio.h>

int main() {
    // 整数型の変数を宣言
    int num1;
    
    // 実数型の変数を宣言
    float num2;
    
    // 文字型の変数を宣言
    char ch;
    
    // 初期値を与えた宣言
    int age = 25;
    
    // 複数の変数を同時に宣言
    int x, y, z;
    
    return 0;
}
```

上記の例では、整数型の変数`num1`、実数型の変数`num2`、文字型の変数`ch`、初期値を与えた整数型の変数`age`、複数の整数型の変数`x`、`y`、`z` を宣言しています。
C 言語では変数のデータ型を指定しなければならないため、それぞれの変数の宣言にはデータ型が指定されています。

# リスト
「**リスト**」とは、複数のデータを格納することができるデータ型です。
前述した変数は1つのデータしか格納できない「箱」に対して、リストは複数のデータを入れることができる「ロッカー」の役割を果たします。
![スクリーンショット 2024-03-19 19.47.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/086940aa-574a-b376-a3db-7208f8346335.png)

リストの1つ1つの箱のことを「**要素**」と言い、それぞれの要素に場所の情報が割り当てられています。
![スクリーンショット 2024-03-19 19.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/3ec79102-4494-b6e3-1ffa-817e7196c90e.png)

各要素の場所の情報にはそれぞれ「**インデックス**」という番号が割り当てられています。
一番左のインデックスは **0** から始まる点に注意しましょう。
![スクリーンショット 2024-03-19 19.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/1cb3a604-9b1a-5abd-f113-6b6222abd8a5.png)

リストの書き方は以下の通りです。
角括弧を使って定義し、それぞれの要素はカンマで区切ります。
```python
変数 = [データ1, データ2, データ3, ...]
```

以下のコードを例にすると、それぞれリストで定義した順に出力されます。
```python
fruits = ['apple', 'banana', 'cherry', 'date']
print(fruits)
```
```:実行結果
['apple', 'banana', 'cherry', 'date']
```

リストから特定の文字列を取得する場合は以下のように定義します。
```python
fruits = ['apple', 'banana', 'cherry', 'date']
# appleを出力する場合
print(fruits[0])
# banana と cherry を出力する場合
print(fruits[1], fruits[2])
```
```:実行結果
apple
banana cherry
```

# 演算子
演算子とは、足し算、引き算などの四則演算や2つの値の大小を比較するときに使う記号のことです。

ここでは以下の演算子について紹介します。
+ **算術演算子**
+ **関係演算子**
+ **論理演算子**
+ **代入演算子**

## 算術演算子
算術演算子とは、足し算、引き算、掛け算、割り算などをするための演算子です。

足し算(+)の場合は **+**
引き算(-)の場合は  **-** 
掛け算(×)の場合は　<b>*</b>
割り算(÷)の場合は　**/**
割り算の計算結果の整数部分だけ求める場合は **//**
割り算の計算結果の余り(剰余)を求める場合は **%** と表されます。

コードの場合、以下のように記述します。
```python
x = 10
y = 2

print(x + y)
print(x - y)
print(x * y)
print(x / y)
print(x // y)
print(x % y)
```
```:実行結果
12
8
20
5.0
5
0
```

ちなみに、5を2回掛けたいような冪乗を表す際は、** のようにアスタリスクを2回使用します。
例えば、5 * 5　という計算は、5を2回掛けているので、5 ** 2 と表すことができます。
```python
print(5 * 5)
print(5 ** 2)
```
```:実行結果
25
25
```

5を5回掛ける場合、掛け算だけだと何回も *5 を書くことになりますが、冪乗を使えば簡単に計算できます。
```python
print(5 * 5 * 5 * 5 * 5)
print(5 ** 5)
```
```:実行結果
3125
3125
```

## 関係演算子
関係演算子は、2つの値の関係が正しいかどうかを判断する演算子です。
例えば、「20」という数字は「10」よりも大きいです。

これを関係演算子で表す場合、
**20 > 10**
と表すことができます。

関係演算子は条件分岐の if 文等でよく使います。

コードで表す場合、結果が正しい場合は「**True**」、正しくない場合は「**False**」が返されます。
```python
x = 10
y = 2

print(x > y)
print(x < y)
```
```:実行結果
True
False
```

以上や以下の場合はそれぞれ「**>=**」「**<=**」を使います。
上記のコードから変数 z に10を代入して再度計算した結果、x は y より大きいので False、x は z と等しいので True が返されます。

```python
x = 10
y = 2
z = 10

print(x <= y)
print(x >= z)
```
```:実行結果
False
True
```

また、比較する2つの値が等しい場合は「**==**」の演算子を使用し、等しくない場合は「**!=**」を使用します。
コードを例にすると、以下のように表示されます。
この場合、10は2と等しくないので == の場合はFalse、!= の場合は True が返ってきます。

```python
x = 10
y = 2

print(x == y)
print(x != z)
```
```:実行結果
False
True
```

## 論理演算子
論理演算子とは、複数の条件を判断させる演算子のことです。
ここでは「**and**」と「**or**」を使用します。

数字の3と8を例にしてコードを記述すると、
and を使用した場合、3 は 5 以上 10 以下ではないので False、
8 は 5 以上 10 以下であるので True が返ってきます。
```python
x = 3
y = 8

print(x >= 5 and x <= 10)
print(y >= 5 and y <= 10)
```
```:実行結果
False
True
```

or を使用した場合、x は3なので、前の条件が一致するので True、
y は8で、いずれの条件も一致しないので False が返ってきます。

```python
x = 3
y = 8

print(x == 3 or x == 3)
print(y == 1 or y == 1)
```
```:実行結果
False
True
```

## 代入演算子
最後に代入演算子です。
代入演算子は「**=**」のことで、これまで変数に値を代入するときに使用してきた演算子です。
また、代入時に足し算や引き算を同時にすることができ、これを「**複合代入演算子**」と言います。

例えば x に10を足して x に代入する場合の式は
**x += 10** です。
z に y を足してから z に代入する方法は
**x += y** です。

これをコードで記述する場合、以下のように計算されます。

```python
x = 8
y = 12
z = 20

x += 10 # 8 + 10 = 18
z += y # 20 + 12 = 32

print(x)
print(z)
```
```:実行結果
18
32
```

# 関数
「**関数**」とは、さまざまな処理を一つにまとめたものです。
関数の使用により、同じ処理を何度も書く必要がなくなり、コードがより簡潔で読みやすくなります。

また、関数は再利用可能であり、プログラムの修正や拡張が容易になります。

関数には2種類あります。
1. 自分で作る関数
2. Python があらかじめ用意してくれている関数

Python があらかじめ用意してくれている関数のことを「**組み込み関数**」と言います。
例えば、これまでコードの結果を表示するために使用してきた print 関数は組み込み関数です。
print 関数がない場合、変数の中身を表示させるために独自にコードを書く必要がありますが、print 関数を使うことで簡単に結果を表示できます。
また、print 関数の内部実装の詳細を知らなくても使うことができます。

## 関数の定義
関数を作ることを「**関数を定義する**」と言います。
Python では関数を定義する場合に **def** を使います。
def の後に関数の名前を書きます。
関数名の後に( )を書き、( )の中に**引数**と呼ばれるデータを記述します。
引数を記述することで、関数内でデータを使うことができます。

```python
def 関数名(引数)
```

以下の関数の例では、引数として与えられた数字を10倍にして返します。

```python
def multiply_by_ten(argument):
    result = argument * 10
    return result
```

このように、関数に引数の値を渡すことで、関数の機能を広範囲に活用できます。

引数という言葉は、「**引数を関数に渡す**」と言ったり、「**引数を関数が受け取る**」と言ったりもします。

なお、引数は必ずしも必要ではありませんし、必要に応じて省略することもできます。
また、引数は複数指定することもでき、その際はカンマで区切って記述します。

```python
def 関数名(引数1,引数2)
```

処理を記述する場合は、引数の後に「:」を入れます。
実行する処理の行は右にインデントする必要があります。
```python
def multiply_by_ten(argument):
    result = argument * 10 # 右にインデントする必要がある
    return result
```

関数の定義が終わったら、インデントを元に戻して初期状態に戻します。
また、関数は引数を受け取ることができ、処理結果を返すこともできます。
これを「**戻り値**」と呼びます。

以下の例では、引数として10を関数に渡し、その結果を表示させます。
戻り値は`return 文`で指定し、結果を関数の外に返します。
```python
def multiply_by_ten(argument):
    result = argument * 10
    return result # 戻り値

print(multiply_by_ten(10)) 
```
```:実行結果
100
```

出力結果は、引数に10を渡した場合の計算結果である100になります。

# クラス
クラスとは、データと処理をまとめたものとなります。
Python ではデータのことを「**属性(アトリビュート)**」と言い、処理のことを「**メソッド**」と言います。
![スクリーンショット 2024-03-25 16.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/5369af25-2990-d086-6a73-4e5f1ebca79d.png)

## 属性とメソッド
属性とは、**クラス内で定義された変数**のことです。
属性は変数と同じように、数値や文字列を代入したり、参照したりすることができます。

クラス内で属性を作ることを「**属性を定義する**」と言います。
![スクリーンショット 2024-03-25 16.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/be9fa6ff-ca35-ab1a-a49d-2cf945b3a22e.png)

ちなみに属性と変数の違いについて、クラスの外にあるかクラスの中にあるかの違いです。
![スクリーンショット 2024-03-25 16.47.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/57a33b08-b933-da2c-6b98-c58e745fac3c.png)

メソッドも関数と同じく、さまざまな処理をまとめて1つにしたものです。
メソッドも関数と同じように def で定義します。
![スクリーンショット 2024-03-25 17.03.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/5672b292-a3d6-d9d7-1155-7f6449c3a2d2.png)

ちなみにメソッドは
 + **インスタンスメソッド**：インスタンスに関連付けられ、そのインスタンスの状態を変更したり、インスタンスの属性にアクセスしたりするために使用
 + **クラスメソッド**：クラス自体に関連付けられ、クラスの状態を変更したり、クラスレベルで操作を行うために使用
 + **スタティックメソッド**：特定のクラスやインスタンスに依存せず、単純な関数としてクラス内に配置されるメソッド
の3種類があります。

まとめると、属性はクラス内の変数、メソッドはクラス内の関数ということになります。
![スクリーンショット 2024-03-25 17.04.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/7531bbed-144d-822a-ffcc-2c6ae26d2a8e.png)

コードの記述例について、以下を用いて説明します。
```python
class Student:
    def avg(self, math, english):
        print((math + english) / 2)

a001 = Student()
a001.avg(80, 70)  
```

最初に `Studentクラス`を、英語の点数の平均を計算する`avgメソッド`をそれぞれ定義します。
その後に`print`関数を使用して、数学と英語の平均点を算出します。

```python
class Student: # Student クラスを定義
    def avg(self, math, english): # avg メソッドを定義
        print((math + english) / 2) # 数学と英語の平均点を算出
```

この中で`def avg(self, math, english):`について、メソッドの場合、関数と違って
**引数を必ず指定する決まりがあります。**
この引数名は任意ですが、「**self**」と書くのが慣習となっています。
言い換えると、メソッドに渡したい引数が無い場合でも、メソッドの引数に self を記述します。

ちなみに、メソッドに渡したい引数が1つの場合は以下のように記述、
```python
class Student:
    def avg(self, 引数1):
        print((math + english) / 2)
```

メソッドに渡したい引数が2つの場合、メソッドの引数に self を含めた合計3つの引数を記述します。
```python
class Student:
    def avg(self, 引数1, 引数2):
        print((math + english) / 2)
```

ここまではメソッドについて説明しましたが、メソッドを定義するのみではクラスを使うことができません。
そのため、以下のように、クラスから作られた「**インスタンス**」を変数に代入してから使用します。
**クラスはインスタンスになって初めて利用する事ができます。**

例えば数学が80点、英語が70点という点数は、a という学級の出席番号001番の人が取ったとします。
ここでは変数名を「a001」とします。
その後にイコールとクラス名を書くことで、クラスを使えるようにします。

クラスを使えるような状態にすることを「**インスタンス化**」「**オブジェクト化**」「**オブジェクト生成**」と表現します。

```python
a001 = Student()  # クラスをインスタンス化する
```

インスタンスは「実体」という意味を持つ英単語で、インスタンス化とは、クラスという設計図から、実際に使える「モノ」を具現化することを指します。

クラスは一度定義しておけば、後からいくらでもインスタンスを生成することができます。
たとえるなら、たい焼きを作る金型が「クラス」であり、その金型から作成されるたい焼きが「インスタンス」となるわけです。
![スクリーンショット 2024-03-25 21.07.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1430519/01e370a1-a718-bcd2-da84-cf966c8a91f1.png)

また、クラスがない場合、それぞれのインスタンスごとに同じ処理を再度記述する必要があるため、手間がかかります。
しかし、クラスを使用することで、同じ処理を効率的に再利用することができます。

話を戻しますが、上記のコードの avg メソッドに80点と70点を渡して実行します。
```python
a001.avg(80, 70)  # 数学が80点、英語が70点の引数をそれぞれ渡す
```

以下のように75点と表示されます。
```python
class Student:
    def avg(self, math, english):
        print((math + english) / 2)

a001 = Student()
a001.avg(80, 70)
```
```:実行結果
75.0
```

補足で属性についても説明します。
属性はクラス内に定義された変数であり、インスタンスに属する「**インスタンス変数**」とクラスに属する「**クラス変数**」の2種類があります。

インスタンス変数は、各インスタンスごとに独立して存在し、インスタンスごとに異なる値を持つことができます。一般的には、コンストラクタ内で初期化されます。

クラス変数は、クラス全体で共有される変数であり、すべてのインスタンスが同じ値を共有します。通常、クラス定義の中で定義され、すべてのインスタンスが同じ値を共有します。

以下のコードではインスタンス変数を例に、`a001`に属性`name`を追加し、その値を代入します。
```python
a001.name = "sato"
```

print 関数で表示させた場合、`sato`と返ってきます。
```python
a001.name = "sato"
print(a001.name)
```
```:実行結果
sato
```

属性はインスタンスごとに存在し、インスタンス化していない場合に属性を定義するとエラーが発生します。
例えば、性別という意味である`gender`というまだ定義していない属性を表示させた場合、以下のエラーが返ってきます。
```python
class Student:
    def avg(self, math, english):
        print((math + english) / 2)

a001 = Student()
print(a001.gender)
```
```:実行結果
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_12476/2866841960.py in <module>
      4 
      5 a001 = Student()
----> 6 print(a001.gender)

AttributeError: 'Student' object has no attribute 'gender'
```

新しいインスタンスを作るごとに、属性を定義する必要がある、というわけです。
そのため、10個インスタンスを作ったとすると、インスタンスごとに属性を10個定義する記述をしなければなりません。
上記の例の場合、「a001.name」のような記述をインスタンスごとに10個、記述しなければなりません。
この不便さを解消するものが「**コンストラクタ**」です。

## コンストラクタ
コンストラクタは、インスタンス化する際に自動的に実行されるメソッドのことです。
コンストラクタは「**初期化メソッド**」とも呼ばれますが、
厳密には、初期化メソッド(`__init__`)はコンストラクタから呼び出されるメソッドです。
`__init__`メソッドの他に`__new__`もコンストラクト処理に関わります。

初期化メソッドは、インスタンス化するときに必ず実行されるメソッドであり、後から使う属性を初期化しておくために使用されます。

コードで記述する場合、以下のようになります。
```python
class Student:
    # コンストラクタ
    def __init__(self):
        self.name = ""  # name 属性の初期化

a001 = Student()  # Student クラスのインスタンス化
a001.name = "sato"  # name 属性に値を代入
print(a001.name)  # "sato" が表示
```

コンストラクタもメソッドなので、`def`から始まり、`__init__`という名前で定義されます。
また、メソッドを定義する際は、最初に`self`を記述するのが慣例です。
`self`はインスタンス自体を指します。次にコンストラクタ内で初期化する属性`name`を定義します。

インスタンス化後、`a001`と`a002`の`name`を表示させてみます。
`a002`の場合、コンストラクタで属性が作成されているため、エラーは発生せず空の値が表示されます。
```python
class Student:
    # コンストラクタ
    def __init__(self):
        self.name = ""  # name 属性の初期化

a001 = Student()  # Student クラスのインスタンス化
a001.name = "sato"  # name 属性に値を代入
print(a001.name)  # "sato" が表示

a002 = Student()  # 新しいインスタンスを作成
print(a002.name)  # コンストラクタで属性が作成されているため、空の値が表示
```
```:実行結果
sato
# 空白
```

属性は、インスタンス化と同時に代入することもできます。
この場合、初期化メソッドの引数に`name`という引数を指定し、その値を代入します。
以下の例では、インスタンス化の際に名前を直接指定しています。
```python
class Student:
    def __init__(self, name):  # コンストラクタを定義
        self.name = name  # インスタンス変数 name を初期化する

a001 = Student("sato")  # インスタンス化と同時に名前を設定
print(a001.name)  # "sato" が表示

a002 = Student("suzuki")  # 別のインスタンスを作成し、名前を指定
print(a002.name)  # "suzuki" が表示
```
```:実行結果
sato
suzuki
```

このようにして、クラスのコンストラクタを使用することで、属性を初期化し、インスタンスごとに異なる値を持たせることができます。

## 参考文献

https://books.mdn.co.jp/books/3217303022/

https://www.youtube.com/watch?v=HyU3XL2F9GE

https://www.kadokawa.co.jp/product/322201000299/