オブジェクト指向プログラミング
クラスの基本
class User:
"""ユーザーを表すクラス"""
# クラス変数(全インスタンスで共有)
user_count = 0
def __init__(self, name, age):
"""コンストラクタ"""
self.name = name # インスタンス変数
self.age = age
User.user_count += 1
def greet(self):
"""インスタンスメソッド"""
return f"こんにちは、{self.name}です({self.age}歳)"
def __str__(self):
"""文字列表現"""
return f"User({self.name}, {self.age})"
def __repr__(self):
return f"User(name='{self.name}', age={self.age})"
# インスタンスの作成
user = User("太郎", 25)
print(user.greet()) # こんにちは、太郎です(25歳)
print(User.user_count) # 1
継承
class Employee(User):
def __init__(self, name, age, company):
super().__init__(name, age) # 親クラスのコンストラクタ
self.company = company
def greet(self):
"""メソッドのオーバーライド"""
return f"{self.company}の{self.name}です"
emp = Employee("花子", 30, "ABC株式会社")
print(emp.greet()) # ABC株式会社の花子です
print(isinstance(emp, User)) # True
プロパティ
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError("絶対零度以下は設定できません")
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
temp = Temperature(100)
print(temp.celsius) # 100
print(temp.fahrenheit) # 212.0
temp.celsius = 0
print(temp.fahrenheit) # 32.0
クラスメソッドとスタティックメソッド
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_str):
"""文字列からDateを作成(ファクトリメソッド)"""
year, month, day = map(int, date_str.split('-'))
return cls(year, month, day)
@staticmethod
def is_leap_year(year):
"""うるう年判定(インスタンス不要)"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
date = Date.from_string("2026-03-15")
print(Date.is_leap_year(2024)) # True
抽象クラス
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# shape = Shape() # TypeError: 抽象クラスはインスタンス化できない
circle = Circle(5)
print(f"面積: {circle.area():.2f}") # 面積: 78.54
データクラス(Python 3.7+)
from dataclasses import dataclass, field
@dataclass
class Product:
name: str
price: int
quantity: int = 0
tags: list = field(default_factory=list)
@property
def total(self):
return self.price * self.quantity
p1 = Product("Python本", 3000, 2)
p2 = Product("Python本", 3000, 2)
print(p1) # Product(name='Python本', price=3000, quantity=2, tags=[])
print(p1 == p2) # True(値による比較)
print(p1.total) # 6000
まとめ
class でクラスを定義、__init__ でコンストラクタ
super() で親クラスのメソッドを呼び出す
@property でゲッター/セッターを実装
@classmethod はクラスメソッド、@staticmethod はスタティックメソッド
ABC で抽象クラスを作る
@dataclass で簡潔にデータ保持クラスを作る