クラスは、データ(属性)と処理(メソッド)をひとまとめにした設計図です。クラスから作られた実体を「インスタンス」と呼びます。オブジェクト指向プログラミングの基本であり、大規模なプログラムを整理するために欠かせない概念です。
この記事では、クラスの定義方法から、コンストラクタ、メソッド、属性の使い方まで詳しく解説します。
基本的な使い方
classキーワードでクラスを定義します。__init__メソッド(コンストラクタ)でインスタンスの初期化を行います。
Python
class User:
def __init__(self, name, age):
self.name = name # インスタンス属性
self.age = age
def greet(self):
print(f"こんにちは、{self.name}です。{self.age}歳です。")
# インスタンスの作成
user1 = User("太郎", 25)
user2 = User("花子", 30)
user1.greet()
user2.greet()
# 属性へのアクセス
print(f"名前: {user1.name}")
print(f"年齢: {user2.age}")
実行結果
こんにちは、太郎です。25歳です。
こんにちは、花子です。30歳です。
名前: 太郎
年齢: 30
selfとは
selfはインスタンス自身を参照する特別な引数です。メソッドの第1引数には必ずselfを書きます。呼び出し時には自動的に渡されるため、明示的に指定する必要はありません。
メソッドの種類
Python
class Calculator:
# クラス属性(全インスタンスで共有)
history = []
def __init__(self, name="電卓"):
self.name = name # インスタンス属性
# インスタンスメソッド
def add(self, a, b):
result = a + b
Calculator.history.append(f"{a} + {b} = {result}")
return result
# クラスメソッド
@classmethod
def show_history(cls):
for record in cls.history:
print(record)
# 静的メソッド
@staticmethod
def is_even(num):
return num % 2 == 0
calc = Calculator("マイ電卓")
print(calc.add(3, 5))
print(calc.add(10, 20))
Calculator.show_history()
print(Calculator.is_even(4))
実行結果
8
30
3 + 5 = 8
10 + 20 = 30
True
特殊メソッド(マジックメソッド)
アンダースコア2つで囲まれた特殊メソッドを定義すると、組み込み関数や演算子の動作をカスタマイズできます。
Python
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return f"{self.name}: {self.price:,}円"
def __repr__(self):
return f"Product('{self.name}', {self.price})"
def __eq__(self, other):
return self.price == other.price
def __lt__(self, other):
return self.price < other.price
p1 = Product("りんご", 200)
p2 = Product("バナナ", 100)
p3 = Product("みかん", 200)
print(p1) # __str__
print(repr(p1)) # __repr__
print(p1 == p3) # __eq__: True
print(p2 < p1) # __lt__: True
# sorted()でも使える
products = [p1, p2, p3]
for p in sorted(products):
print(f" {p}")
実行結果
りんご: 200円
Product('りんご', 200)
True
True
バナナ: 100円
りんご: 200円
みかん: 200円
プロパティ
@propertyデコレータを使うと、メソッドを属性のようにアクセスできます。
Python
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径は0以上である必要があります")
self._radius = value
@property
def area(self):
return 3.14159 * self._radius ** 2
c = Circle(5)
print(f"半径: {c.radius}")
print(f"面積: {c.area:.2f}")
c.radius = 10
print(f"半径: {c.radius}")
print(f"面積: {c.area:.2f}")
実行結果
半径: 5
面積: 78.54
半径: 10
面積: 314.16
クラス属性とインスタンス属性の違い
クラス属性は全インスタンスで共有されます。リストや辞書などのミュータブルなクラス属性を変更すると、全インスタンスに影響します。インスタンスごとに独立したデータが必要な場合は、__init__内でインスタンス属性として定義しましょう。
まとめ
classでデータと処理をまとめた設計図を定義する__init__でインスタンスの初期化、selfでインスタンス自身を参照- 特殊メソッド(
__str__,__eq__等)で組み込み操作をカスタマイズ @propertyで属性のようにアクセスできるメソッドを定義- クラス属性とインスタンス属性の違いを理解する