今回の講座では何かと挫折者が多いpythonのclassの基本について、初学者向けにマルっと分かりやすく解説していきます。
データサイエンスやデータ分析の現場において、classを使う機会はそこまで多くありません。
しかし、全く使わないというわけでもありませんし、知らないと正直なめられます。
「えっ、分かんないんだ~」っとならないためにもしっかりと押さえていきましょう!
クラスを学ぶ上で大事な事は単語を覚える事です。
インスタンスやオブジェクト指向など新しい単語が出てきますが、言っている事は非常に簡単です。
ついつい単語の意味を覚えるのは後回しにしがちですが、まずしっかりと覚える事が大事です。
クラスとは?
まずは、クラスとは何なのか?使うと何が嬉しいのか?その点から解説していきたいと思います。
「クラス」は、オブジェクト(物)の設計図のようなものです。
クラスを使うことで、特定の種類のオブジェクトを効率的に定義し、それをもとに複数のオブジェクト(物)を作り出すことができます。
クラスを元に作られたオブジェクトのことを「インスタンス」と呼びます。
- インスタンス:クラスから作られたオブジェクトのこと
例えるなら、クラスは「車の設計図」で、インスタンスはその設計図を元に作られた個々の車です。
設計図(クラス)はひとつでも、そこからいろいろな色やモデルの車(インスタンス)を作成することができます。
クラスを使うメリット
クラスを使うことで、プログラムをシンプルかつ効率的に設計できるようになります。具体的なメリットとしては次のような点があります。
- コードの再利用性が高まる
- コードの可読性が上がる
- メンテナンス性の向上
まずコードの再利用が高まります。
一度クラスを定義すれば、そのクラスを使って何度もオブジェクトを生成できます。同じコードを繰り返し書く必要がなく効率的になります。
特にチームで開発する時に、チーム内での使い回しも出来るので非常に便利です。
コードの可読性も上がります。
クラスを使うことで、データとその操作方法(メソッド)をまとめることができ、プログラム全体の構造をわかりやすく整理できます。
実際の業務では、コードを書く時間よりも読む時間の方が多いという状況は非常に多いので、可読性は重要です。
またメンテナンス性も向上します。
クラスを使う事で、時間が経ってからも修正や拡張がしやすくなります。
チーム全員が同じ構造に基づいて開発できるため、後からの変更や追加に対する対応もスムーズです。
オブジェクト指向とは?
オブジェクト指向プログラミング(OOP)は、データとその操作をひとつの「オブジェクト」としてまとめて扱うプログラミングスタイルです。
オブジェクト指向を使うと、プログラムの部品を使いまわしてコードを整理しやすくなるため、特に複雑なプログラムで力を発揮します。
もう一度「車」の場合を考えてみましょう。
車には、色やモデルといった特徴(属性)があります。また、車には走るや止まるといった動作(メソッド)もあります。
このように、属性と動作を一緒にまとめて扱うのが「オブジェクト指向」です。
例えば、車の設計図からたくさんの色違いの車を量産するイメージです。
そしてこの作成された車の事をオブジェクトとも言います。
オブジェクトとインスタンスの違い
クラスの勉強をしていると良く分からなくなってくるのがオブジェクトとインスタンスの違いでしょう。
しかし、難しい事は考えなくて大丈夫です。
ほぼ同じものという認識で大丈夫です。
先ほど、クラスから生成されたものはインスタンスと言いましたが、これはオブジェクトでもあります。
簡単にまとめると、
- インスタンス:クラスから生成されたもの
- オブジェクト:データとその操作をまとめた実体として定義される。Pythonでは、全てのものがオブジェクトあり、クラスや関数もオブジェクト。intやstrのようなデータ型もオブジェクト
このようにインスタンスはオブジェクトに包含されているイメージです。
クラスを作ってみよう
前置きが長くなりましたが、実際にクラスの作り方を見ていきましょう。
実際にクラスを作るのが一番理解に繋がりますからね!
クラスの定義
では実際に車を作成するクラスを定義してみましょう!
1 2 3 4 5 6 7 8 9 10 11 12 |
# クラスの定義 class Car: def __init__(self, color, model): self.color = color # 車の色(属性) self.model = model # 車のモデル(属性) def drive(self): print(f"{self.color}い{self.model}が走ります!") # 車が走る(動作) # インスタンスの作成 my_car = Car("赤", "セダン") my_car.drive() # セダンが走ります! |
このようにする事で赤いセダンが走ります。
この時大事なポイントとしては、まず関数などと同じく、クラス内ではインデントを下げて記述します。
コンストラクタ
上記のコードではdef __init__という初出のコードがありましたね!
これはコンストラクタと呼ばれるものです。
コンストラクタとは、オブジェクトが生成されるときに自動的に呼び出されるメソッドです。
このメソッドは、インスタンス(オブジェクト)を作成した直後に、オブジェクトの初期設定を行うために利用されます。
例えば、上記のCarクラスでは車が生成される際に「色」や「モデル」といった初期状態を設定したいですよね。この設定をコンストラクタで行っています。
1 |
my_car = Car("赤", "セダン") |
この例では、Carクラスのコンストラクタが「色」と「モデル」を受け取って、それをインスタンスの属性(self.colorとself.model)に保存しています。
インスタンスが作成されると、自動的にこのコンストラクタが呼び出され、オブジェクトが初期化されます。
上記のクラスでは、コンストラクタの下にdriveメソッドがありますね。
1 |
def drive(self): print(f"{self.color}い{self.model}が走ります!") # 車が走る(動作) |
こちらはインスタンスを作成した直後に自動で呼び出されるわけではありません。
ですので、コンストラクタにprint文を持ってくると、インスタンスが作成された時点でprint文が実行されます。
1 2 3 4 5 6 7 |
class Car: def __init__(self, color, model): self.color = color # 車の色(属性) self.model = model # 車のモデル(属性) print(f"{self.color}い{self.model}です。") red_car = Car("赤", "フェラーリ") |
->赤いフェラーリです。
また、インスタンスを作成する際はコンストラクタで指定している引数の数は必ず指定しないといけません。
1 |
red_car = Car("赤") |
このように、color引数しか指定していない状態だとエラーになってしまいます。
selfとは?
クラスではコンストラクタやメソッドの第一引数にselfを指定しています。
これは関数などでは無かったことですが、クラスの場合はこの書き方が必須になってきます。
selfは、クラスのメソッド内でオブジェクト自身を指す特別なキーワードです。メソッドや属性にアクセスする際に、自分自身を指すために使われます。
例として、__init__メソッドの中でself.color = colorという記述がありますが、これは「このオブジェクト(インスタンス)のcolor属性に、引数として渡されたcolorの値を代入する」という意味です。
selfを使うことで、他のメソッドでもオブジェクトの属性にアクセスできます。
まずは第一引数にselfという事を覚えておきましょう。
属性とは?
クラスを学ぶ上で覚えておいて欲しいものとして属性があります。
属性とは、クラスのインスタンスに属するデータのことです。
属性はクラス内で定義され、インスタンスごとに異なる値を持つことができます。
例えば、先ほどの車の例では、「色」や「モデル」が属性に当たります。
属性にアクセスしたり、変更する方法はとても簡単です。ドット記法を使って、以下のようにインスタンスの属性にアクセスできます。
1 2 3 |
# 属性にアクセスする print(my_car.color) # 結果: 赤 print(my_car.model) # 結果: セダン |
また、属性は後から変更する事もできます。
1 2 3 |
# 属性を変更する my_car.color = "青" print(my_car.color) # 結果: 青こ |
このようにすることで色の変更ができます。
メソッドの定義
すでに出てきていますが、クラスに関連づけられるものとして、属性の他にメソッドがあります。
メソッドは、クラスの中に定義された関数で、クラスのインスタンスに属します。関数と同様に、引数を受け取り、処理を行い、その結果を返すことができます。ただし、クラス内に定義されているため、オブジェクトの属性にアクセスしたり、オブジェクトの状態を変更する役割を持ちます。
メソッドの基本構造
メソッドは、通常クラスの内部で定義され、少なくとも一つの引数を持ちます。この引数は通常selfと呼ばれ、メソッドが呼び出されたオブジェクト自身を指します。selfを通じて、そのオブジェクトの属性や他のメソッドにアクセスできます。
メソッドの基本的な書き方
1 2 3 4 |
class クラス名: def メソッド名(self, 引数1, 引数2, ...): # メソッドの処理 return 結果 |
- self: メソッドがそのオブジェクト自身に対して操作を行うために必要です。Pythonでは、インスタンスメソッドの最初の引数としてselfを必ず指定します。
- return: メソッドが処理結果を返す場合に使用します。必須ではありませんが、値を返す際に使われます。
先ほどのクラスの例ではdriveメソッドが作成されていますね。
もちろんメソッドは1つだけでなく、複数作成する事ができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# クラスの定義 class Car: def __init__(self, color, model): self.color = color # 車の色(属性) self.model = model # 車のモデル(属性) def drive(self): print(f"{self.color}い{self.model}が走ります!") # 車が走る(動作) def stop(self): print(f"{self.color}い{self.model}が止まります!") my_car = Car("赤", "セダン") my_car.drive() my_car.stop() |
->赤いセダンが走ります!
赤いセダンが止まります!
このコードでは、Carクラスの中に2つのメソッド、driveとstopを定義しています。これらのメソッドを使うことで、車が「走る」「止まる」といった動作を表現しています。
メソッドを呼び出すには、my_carのように作成したインスタンスに.でつなぎ、メソッド名を書く事で呼び出すことができます。
引数付のメソッド
メソッドにはself以外の引数を追加することもできます。
引数を使うことで、メソッドに動的な値を渡し、柔軟な動作を実現できます。
下記の例では、drive_speedメソッドにspeedという引数を追加し、その値を使って車の速度を表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Car: def __init__(self, color, model): self.color = color self.model = model def drive_speed(self, speed): print(f"{self.color}い{self.model}が時速{speed}kmで走っています!") # インスタンスを作成 my_car = Car("青", "SUV") # 引数を渡してメソッドを呼び出す my_car.drive_speed(80) |
->青いSUVが時速80kmで走っています!
戻り値のあるメソッドの例
メソッドは、通常の関数と同様に、returnを使って値を返すことができます。
これにより、メソッドの結果を他の処理に利用することができます。
下記の例ではCaluculatorクラスを作成し、引数に入れた数字を足し算するメソッドと、掛け算するメソッドを作成しています。
そして、インスタンスを作成し、メソッドを使い受け取った戻り値を変数rasult_addとresult_mltに代入しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Calculator: def add(self, a, b): return a + b def multiply(self, a, b): return a * b # インスタンスを作成 calc = Calculator() # メソッドを使って計算し、戻り値を受け取る result_add = calc.add(10, 20) # 結果: 30 result_mlt = calc.multiply(5, 3) # 結果: 15 |
はい、以上です!
今回の内容が分かればクラスの基礎はしっかりと身についています。
実際に手を動かしながら、どんどんクラスを作成し自分のものにしていきましょう。
pythonの基礎から復習したいという人は下記の講座をどうぞ!
