Pythonデータモデル入門(ハンズオン)!3.3

当サイトではアフィリエイト広告を利用しています。

リファレンス

Pythonの**データモデル(Data Model)は、クラスやオブジェクトの振る舞いを決める重要な仕組みです。
特に、__init____str__ などの
特殊メソッド(マジックメソッド)**を活用することで、オブジェクトの動作を自由にカスタマイズできます。

本記事では、初心者でも理解しやすいように、実際のコードを使いながら解説していきます!✨


📌 1. クラスを作る基本

Pythonでクラスを作るには class を使います。
まずは、シンプルな Person クラスを作成し、オブジェクトを作ってみましょう。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# インスタンスを作成
p = Person("Alice", 25)
print(p)  # 何が出力される?

🔹 実行すると、以下のようなわかりにくい表示になります。

<__main__.Person object at 0x7f8b5c3d3c10>

このままだと人間にとって読みにくいですね…。
そんなときは __str__ を使って「見やすく」する のがポイントです!


📌 2. __str__ でオブジェクトを見やすくする

__str__ を実装すると、print(オブジェクト)分かりやすい表現ができます!

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"名前: {self.name}, 年齢: {self.age}歳"

p = Person("Alice", 25)
print(p)  # 名前: Alice, 年齢: 25歳

🔹 これで print(p) の出力が見やすくなりました!


📌 3. __repr__ でデバッグしやすくする

__repr__ を実装すると、オブジェクトのデバッグ用表現が定義できます。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age})"

p = Person("Alice", 25)
print(repr(p))  # Person(name='Alice', age=25)

🔹 repr(オブジェクト) を使うと、プログラム的に分かりやすい形式で表示できます。


📌 4. __len__ で len(オブジェクト) を定義

__len__ を定義すると、オブジェクトに len() を使えるようになります。

class Team:
    def __init__(self, members):
        self.members = members

    def __len__(self):
        return len(self.members)

team = Team(["Alice", "Bob", "Charlie"])
print(len(team))  # 3

🔹 オブジェクトの長さを len(オブジェクト) で取得できるようになりました!


📌 5. __getitem__ でインデックスアクセス

リストのように オブジェクト[index] でアクセスしたい場合、__getitem__ を実装します。

class Team:
    def __init__(self, members):
        self.members = members

    def __getitem__(self, index):
        return self.members[index]

team = Team(["Alice", "Bob", "Charlie"])
print(team[1])  # Bob

🔹 これで リストのようにインデックスでアクセス できるようになりました!


📌 6. __call__ でオブジェクトを関数のように使う

__call__ を定義すると、オブジェクトを関数のように扱えます。

class Greeter:
    def __init__(self, greeting):
        self.greeting = greeting

    def __call__(self, name):
        return f"{self.greeting}, {name}!"

greet = Greeter("Hello")
print(greet("Alice"))  # Hello, Alice!
print(greet("Bob"))    # Hello, Bob!

🔹 greet("Alice") のように、オブジェクトを関数のように使えるようになりました!


📌 7. __eq__ で == の動作をカスタマイズ

__eq__ を実装すると、オブジェクトの等価性を定義できます。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        return self.name == other.name and self.age == other.age

p1 = Person("Alice", 25)
p2 = Person("Alice", 25)
p3 = Person("Bob", 30)

print(p1 == p2)  # True
print(p1 == p3)  # False

🔹 オブジェクトの「意味的な等価性」を定義できます!


📌 8. __add__ で + の動作をカスタマイズ

例えば、Person クラスに + を定義できます。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __add__(self, other):
        return Person(self.name + " & " + other.name, self.age + other.age)

p1 = Person("Alice", 25)
p2 = Person("Bob", 30)
p3 = p1 + p2

print(p3.name)  # Alice & Bob
print(p3.age)   # 55

🔹 オブジェクト同士を + で合成できるようになりました!


📌 9. __enter__ / __exit__ で with 構文を使う

with 文で使えるオブジェクトを作るには、__enter__ / __exit__ を実装します。

class FileOpener:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.file = open(self.filename, 'w')
        return self.file

    def __exit__(self, exc_type, exc_value, traceback):
        self.file.close()

# with を使う
with FileOpener("test.txt") as f:
    f.write("Hello, World!")

print("ファイルに書き込み完了!")

🔹 with を使うと、ファイルの自動クローズ などが可能になります!


🔹 まとめ

特殊メソッド 役割
__str__ print(obj) の出力を定義
__repr__ repr(obj) の出力を定義
__len__ len(obj) を定義
__getitem__ obj[index] を定義
__call__ obj() で呼び出せる
__eq__ == の比較を定義
__add__ + の挙動を定義
__enter__ / __exit__ with 構文をサポート

Pythonのデータモデルを活用すると、オブジェクトをより直感的に扱えるようになります!ぜひ試してみてください! 🚀