チュートリアル

Python基礎構文:クラスとオブジェクト

Python入門クラスオブジェクト指向
広告エリア

はじめに

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基礎構文シリーズは完了です。基本的な構文を理解したら、実際にコードを書いて練習することが上達への近道です。

広告エリア