Pythonのクラスとオブジェクト指向入門【初心者向け解説】
PythonをコマンドプロンプトやPowerShellでPC上で動かすには、Pythonをダウンロードしてインストールする必要があります。
まだの方はPythonのインストールと開発環境の構築の記事を参考にして、Pythonをインストールしてください。
Web開発の世界に足を踏み入れたばかりの皆さん、こんにちは!今回は、多くのプログラミング言語で採用されている重要な考え方、「オブジェクト指向プログラミング(OOP)」と、その中核をなすPythonの「クラス」について、どこよりも分かりやすく解説していきます。専門用語に尻込みする必要はありません。この記事を読み終える頃には、「なるほど、そういうことか!」と、きっと納得できるはずです。
この記事の最大の目標は、皆さんに「コードが動く楽しさ」を体験してもらうことです。難しい理論は後回しにして、まずはコピペで動くコードを触りながら、オブジェクト指向の便利さを実感していきましょう!
オブジェクト指向って、そもそも何?
「オブジェクト指向」と聞くと、なんだか難しそうですよね。でも、実は私たちの身の回りに溢れている考え方なんです。
一番よく使われる例えが「たい焼きの型」と「たい焼き」です。
- クラス (Class): たい焼きの「型」のこと。どんな形をしていて、どんな材料(あんこ、クリームなど)を入れるか、といった設計図の役割を果たします。
- オブジェクト (Object): たい焼きの「型」から作られた、一つひとつの「たい焼き」そのものです。同じ型から作られても、中身のあんこが違ったり、少し焦げ目がついていたり、それぞれが個性を持っています。
プログラミングの世界では、この「設計図(クラス)」を一度作ってしまえば、そこから具体的な「モノ(オブジェクト)」を効率的に、しかも大量に作り出せるようになります。これがオブジェクト指向の基本的な考え方です。Webサイトで言えば、「ユーザー」や「ブログ記事」、「商品」といった要素をそれぞれオブジェクトとして扱うことで、複雑なシステムもスッキリと整理できるのです。
Pythonクラスの基本:設計図を作ってみよう
それでは、さっそくPythonでクラスという「設計図」を作ってみましょう。ここでは、犬(Dog)をテーマに進めていきます。
1. 最もシンプルなクラス
まずは、中身が空っぽのクラスを定義します。これだけでも立派な「設計図」です。
# Dogという名前のクラス(設計図)を定義
class Dog:
pass # passは「何もしない」という意味。中身が空の場合に記述します。
# Dogクラスから、具体的な犬のオブジェクト(インスタンス)を作成
my_dog = Dog()
# my_dogがどんなものか表示してみる
print(my_dog)
実行結果:
<__main__.Dog object at 0x10e28a2d0>
実行結果を見ると、`Dog` というクラスのオブジェクトが作成されたことが分かりますね。(`0x...`の部分は実行環境によって変わります)
2. 初期化メソッド `__init__` で個性を与える
次に、たい焼きにあんこを入れるように、犬に「名前」や「犬種」といった具体的な情報(プロパティや属性と呼びます)を持たせてみましょう。そのために使うのが `__init__` という特別なメソッド(クラス内の関数のこと)です。これは、オブジェクトが作られた瞬間に自動的に実行される、初期設定用のメソッドです。
class Dog:
# オブジェクト作成時に自動で呼ばれる初期化メソッド
def __init__(self, name, breed):
# self.変数名 の形で、オブジェクトにデータを保存する
self.name = name
self.breed = breed
print(f"{self.name}({self.breed})が生まれました!")
# 「ポチ」という名前の「柴犬」オブジェクトを作成
dog1 = Dog("ポチ", "柴犬")
# 「ハチ」という名前の「秋田犬」オブジェクトを作成
dog2 = Dog("ハチ", "秋田犬")
# それぞれの名前と犬種を表示してみる
print(f"1匹目の名前: {dog1.name}")
print(f"1匹目の犬種: {dog1.breed}")
print(f"2匹目の名前: {dog2.name}")
print(f"2匹目の犬種: {dog2.breed}")
`__init__` の最初の引数 `self` は、作られるオブジェクト自身を指す特別なキーワードです。おまじないのようなものだと思ってください。「このオブジェクト自身の名前は〇〇です」というように、`self.name = name` とすることで、オブジェクトにデータを紐付けています。
実行結果:
ポチ(柴犬)が生まれました!
ハチ(秋田犬)が生まれました!
1匹目の名前: ポチ
1匹目の犬種: 柴犬
2匹目の名前: ハチ
2匹目の犬種: 秋田犬
`Dog("ポチ", "柴犬")` のようにクラスを呼び出すだけで、`__init__` が実行され、それぞれの情報を持ったオブジェクトが作成されました。`dog1.name` のように `.` (ドット) で繋ぐことで、そのオブジェクトが持つ情報にアクセスできます。
3. メソッドで振る舞いを定義する
オブジェクトはデータ(属性)だけでなく、「振る舞い(メソッド)」も持つことができます。犬なら「鳴く」という振る舞いを追加してみましょう。
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
# 犬が鳴く、という振る舞い(メソッド)を追加
def bark(self):
return f"{self.name}: ワンワン!"
# オブジェクトを作成
my_dog = Dog("コロ", "雑種")
# barkメソッドを呼び出す
greeting = my_dog.bark()
print(greeting)
クラスの中に、`def` を使って関数を定義するだけです。このときも、最初の引数には必ず `self` を書くのを忘れないでください。`self` を通して、そのオブジェクト自身の名前(`self.name`)にアクセスできます。
実行結果:
コロ: ワンワン!
応用編:クラスの「継承」で設計図を再利用する
オブジェクト指向が本当に強力なのは、ここからです。「継承」という仕組みを使うと、既存のクラス(設計図)を元にして、機能を追加・変更した新しいクラスを簡単に作ることができます。
例えば、先ほどの `Dog` クラスを元に、新たに「盲導犬(GuideDog)」クラスを作ってみましょう。盲導犬は犬の一種なので、「名前」や「犬種」を持ち、「鳴く」という基本的な機能は同じです。それに加えて、「人を助ける」という特別な仕事(メソッド)を持っています。
# 元になる親クラス(スーパークラス)
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
print(f"犬の{self.name}が誕生。犬種は{self.breed}です。")
def bark(self):
return f"{self.name}: ワン!"
# Dogクラスを継承して新しい子クラス(サブクラス)を作成
class GuideDog(Dog): # カッコの中に親クラスの名前を書く
def assist(self):
return f"{self.name}は、人を安全に誘導しています。"
# 盲導犬オブジェクトを作成
g_dog = GuideDog("エル", "ラブラドール・レトリバー")
# 親クラス(Dog)のメソッドも使える
print(g_dog.bark())
# 子クラス(GuideDog)で追加した独自のメソッド
print(g_dog.assist())
`class GuideDog(Dog):` のように、クラス名の後のカッコに元にしたいクラス名を書くだけで継承完了です。これだけで、`GuideDog` は `Dog` の属性(`name`, `breed`)とメソッド(`bark`)をすべて受け継ぎます。コードの再利用性が高まり、とても効率的ですね。
実行結果:
犬のエルが誕生。犬種はラブラドール・レトリバーです。
エル: ワン!
エルは、人を安全に誘導しています。
実践例:ブログ記事を管理するクラス
では、もっとWeb制作の現場に近い例を見てみましょう。ブログサイトの記事を管理する `BlogPost` クラスを作ります。記事には「タイトル」「本文」「著者」があり、「要約を表示する」機能を持たせます。
import textwrap
class BlogPost:
def __init__(self, title, content, author):
self.title = title
self.content = content
self.author = author
# 記事の情報をきれいに表示するメソッド
def display(self):
print("--------------------")
print(f"タイトル: {self.title}")
print(f"著者: {self.author}")
print("--- 本文 ---")
# 長い文章を折り返して表示
print(textwrap.fill(self.content, width=40))
print("--------------------")
# 複数の記事オブジェクトを作成
post1 = BlogPost(
"Pythonクラス入門",
"オブジェクト指向は、プログラムを部品のように組み立てる考え方です。クラスは設計図、オブジェクトは実体です。",
"Taro Yamada"
)
post2 = BlogPost(
"Webデザインの基本",
"良いデザインは、見た目の美しさだけでなく、ユーザーの使いやすさを第一に考えます。余白や配色が重要です。",
"Hanako Sato"
)
# 記事を表示
post1.display()
post2.display()
このように、一つひとつの記事をオブジェクトとして扱うことで、データ(タイトルなど)と振る舞い(表示機能)がひとまとめになり、管理がとても楽になります。
実行結果:
--------------------
タイトル: Pythonクラス入門
著者: Taro Yamada
--- 本文 ---
オブジェクト指向は、プログラムを部品のように組み立てる考え方です。クラスは設計図、オブジェクトは実体です。
--------------------
--------------------
タイトル: Webデザインの基本
著者: Hanako Sato
--- 本文 ---
良いデザインは、見た目の美しさだけでなく、ユーザーの使いやすさを第一に考えます。余白や配色が重要です。
--------------------
【動かして体験!】完全なPythonコードのサンプル
お待たせしました!ここでは、これまでの内容をまとめた「ユーザー管理プログラム」の完全なコードを紹介します。 このコードは、そのまま `.py` ファイルとして保存し、お使いのコンピュータのターミナル(またはコマンドプロンプト)で実行できます。「動く」を体験してみてください!
実行方法
- 下記のコード全体をコピーします。
- テキストエディタ(VSCodeなど)に貼り付け、`user_manager.py` という名前で保存します。
- ターミナルを開き、保存したファイルがあるディレクトリに移動します。
- `python user_manager.py` と入力してEnterキーを押します。
もし、お使いのPCにPythonがインストールされていない場合は、python.org からダウンロードしてください。
# user_manager.py
class User:
"""
Webサイトのユーザー情報を表すクラス
"""
def __init__(self, user_id, name, email):
self.user_id = user_id
self.name = name
self.email = email
self.is_active = True # デフォルトでアクティブユーザー
def get_profile(self):
"""
ユーザーのプロフィール情報を整形して返す
"""
status = "アクティブ" if self.is_active else "無効"
return f"ID: {self.user_id}\n名前: {self.name}\nメール: {self.email}\nステータス: {status}"
def deactivate(self):
"""
ユーザーを無効化する
"""
self.is_active = False
print(f"ユーザー「{self.name}」を無効化しました。")
# メインの処理を実行する部分
if __name__ == "__main__":
# ユーザーのオブジェクトを複数作成
user1 = User("web-creator", "田中 太郎", "tanaka@example.com")
user2 = User("designer-sato", "佐藤 花子", "sato@example.com")
# プロフィールを表示
print("--- ユーザー一覧 ---")
print(user1.get_profile())
print("-" * 20)
print(user2.get_profile())
print("\n" + "=" * 20 + "\n")
# 一人のユーザーを無効化してみる
user2.deactivate()
print("\n--- 変更後のユーザー一覧 ---")
print(user1.get_profile())
print("-" * 20)
print(user2.get_profile())
このコードを実行すると、ターミナルには次のように表示されるはずです。
実行結果のイメージ:
--- ユーザー一覧 ---
ID: web-creator
名前: 田中 太郎
メール: tanaka@example.com
ステータス: アクティブ
--------------------
ID: designer-sato
名前: 佐藤 花子
メール: sato@example.com
ステータス: アクティブ
====================
ユーザー「佐藤 花子」を無効化しました。
--- 変更後のユーザー一覧 ---
ID: web-creator
名前: 田中 太郎
メール: tanaka@example.com
ステータス: アクティブ
--------------------
ID: designer-sato
名前: 佐藤 花子
メール: sato@example.com
ステータス: 無効
どうでしょうか?クラスを使うことで、ユーザー情報とその操作(無効化など)がスッキリとまとまり、コードが読みやすくなっているのが感じられると思います。
気をつけるべき点・よくある間違い
最後に、初心者がクラスを扱う上でつまずきやすいポイントをいくつか紹介します。
- `self` のつけ忘れ: メソッドを定義するとき、第一引数に `self` を書くのを忘れたり、メソッド内で属性にアクセスするときに `self.name` のように `self.` をつけ忘れるとエラーになります。「クラス内のことは `self` を通して」と覚えましょう。
- `__init__` のスペルミス: `__init__` は、前後にアンダースコアが2つずつです。`_init_` のように1つにすると、ただのメソッドと解釈され、初期化メソッドとして自動的に呼ばれなくなります。
- インスタンス化の `()` を忘れる: `my_dog = Dog` のように `()` をつけ忘れると、オブジェクトが作られず、クラスそのものが変数に代入されてしまいます。`my_dog = Dog()` のように必ずカッコをつけましょう。
次のステップへ
クラスとオブジェクト指向の基本が分かったら、次はPythonの便利な標準ライブラリを使ってみましょう。プログラムで日付や時刻を扱うことは非常によくあります。
次の記事では、`datetime` モジュールを使って、現在の日付を取得したり、日付の計算をしたりする方法を学びます。
→ datetimeモジュールで日付と時刻を扱う方法