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