はじめに
Python基礎構文シリーズ最終回は「クラスとオブジェクト」です。オブジェクト指向プログラミングの基本を学びます。
クラスとは
クラスは、データ(属性)と処理(メソッド)をまとめた設計図のようなものです。クラスから作成された実体を「オブジェクト」または「インスタンス」と呼びます。
基本的なクラス定義
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"こんにちは、{self.name}です!")
# インスタンスの作成
user1 = User("太郎", 25)
user2 = User("花子", 22)
# 属性へのアクセス
print(user1.name) # 太郎
print(user2.age) # 22
# メソッドの呼び出し
user1.greet() # こんにちは、太郎です!
__init__ メソッド(コンストラクタ)
インスタンス作成時に自動的に呼び出されるメソッドです。
class Product:
def __init__(self, name, price, stock=0):
self.name = name
self.price = price
self.stock = stock
# 引数を渡してインスタンス作成
product1 = Product("りんご", 150, 100)
product2 = Product("みかん", 80) # stockはデフォルト値0
print(product1.stock) # 100
print(product2.stock) # 0
インスタンスメソッド
self を第一引数に取るメソッドです。
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
"""入金"""
self.balance += amount
print(f"{amount}円入金しました。残高: {self.balance}円")
def withdraw(self, amount):
"""出金"""
if amount > self.balance:
print("残高不足です")
return False
self.balance -= amount
print(f"{amount}円出金しました。残高: {self.balance}円")
return True
# 使用例
account = BankAccount("太郎", 10000)
account.deposit(5000) # 5000円入金しました。残高: 15000円
account.withdraw(3000) # 3000円出金しました。残高: 12000円
account.withdraw(20000) # 残高不足です
クラス変数とインスタンス変数
class Dog:
# クラス変数(全インスタンスで共有)
species = "犬"
count = 0
def __init__(self, name):
# インスタンス変数(各インスタンス固有)
self.name = name
Dog.count += 1
dog1 = Dog("ポチ")
dog2 = Dog("タロウ")
print(Dog.species) # 犬
print(Dog.count) # 2
print(dog1.species) # 犬(クラス変数にもアクセス可能)
print(dog1.name) # ポチ
継承
既存のクラスを拡張して新しいクラスを作成できます。
# 親クラス(基底クラス)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
# 子クラス(派生クラス)
class Dog(Animal):
def speak(self):
return f"{self.name}: ワンワン!"
class Cat(Animal):
def speak(self):
return f"{self.name}: ニャーニャー!"
# 使用例
dog = Dog("ポチ")
cat = Cat("タマ")
print(dog.speak()) # ポチ: ワンワン!
print(cat.speak()) # タマ: ニャーニャー!
super()で親クラスのメソッドを呼び出す
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__を呼び出し
self.breed = breed
dog = Dog("ポチ", "柴犬")
print(dog.name) # ポチ
print(dog.breed) # 柴犬
プライベート属性
アンダースコアで始まる属性は「外部からアクセスしないでね」という慣例です。
class User:
def __init__(self, name, password):
self.name = name
self._password = password # プライベート(慣例)
def check_password(self, password):
return self._password == password
user = User("太郎", "secret123")
print(user.check_password("secret123")) # True
# アクセスは可能だが、推奨されない
print(user._password) # secret123
ダブルアンダースコアで始まる属性は、名前がマングリング(変更)されます。
class User:
def __init__(self):
self.__secret = "秘密"
user = User()
# print(user.__secret) # エラー
print(user._User__secret) # アクセス可能だが非推奨
プロパティ(getter/setter)
属性へのアクセスを制御できます。
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
circle = Circle(5)
print(circle.radius) # 5
print(circle.area) # 78.53975
circle.radius = 10
print(circle.area) # 314.159
# circle.radius = -1 # ValueError
# circle.area = 100 # AttributeError(setterがないため)
特殊メソッド(マジックメソッド)
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""print()時の表示"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""デバッグ用の表示"""
return f"Vector(x={self.x}, y={self.y})"
def __add__(self, other):
"""+ 演算子"""
return Vector(self.x + other.x, self.y + other.y)
def __eq__(self, other):
"""== 演算子"""
return self.x == other.x and self.y == other.y
def __len__(self):
"""len() 関数"""
return int((self.x ** 2 + self.y ** 2) ** 0.5)
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print(v1) # Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 == v2) # False
print(len(v1)) # 5
クラスメソッドと静的メソッド
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@classmethod
def from_string(cls, date_string):
"""文字列からインスタンスを作成"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day)
@staticmethod
def is_valid_date(year, month, day):
"""日付が有効かチェック"""
return 1 <= month <= 12 and 1 <= day <= 31
# 通常のインスタンス作成
date1 = Date(2026, 1, 28)
# クラスメソッドでインスタンス作成
date2 = Date.from_string("2026-01-28")
# 静的メソッド(インスタンス不要)
print(Date.is_valid_date(2026, 13, 1)) # False
データクラス(Python 3.7+)
シンプルなクラスを簡潔に定義できます。
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
email: str = ""
user = User("太郎", 25)
print(user) # User(name='太郎', age=25, email='')
# 自動で__eq__も生成される
user2 = User("太郎", 25)
print(user == user2) # True
まとめ
class クラス名:でクラスを定義__init__はコンストラクタselfは自身のインスタンスを指す- 継承:
class 子クラス(親クラス): @propertyで属性アクセスを制御- 特殊メソッド:
__str__,__add__,__eq__など @classmethod,@staticmethodでクラスレベルのメソッド
これでPython基礎構文シリーズは完了です。基本的な構文を理解したら、実際にコードを書いて練習することが上達への近道です。