Dunder Methods
Dunder methods คืออะไร?
หัวข้อที่มีชื่อว่า “Dunder methods คืออะไร?”Dunder methods (ย่อมาจาก double-underscore) เป็น special methods เช่น __repr__, __eq__ และ __add__ ที่ Python เรียกอัตโนมัติเพื่อตอบสนองต่อ built-in syntax และฟังก์ชัน
สิ่งเหล่านี้เป็นกลไกเบื้องหลัง Python Data Model — สัญญาที่ทำให้ object ของคุณทำงานเหมือน built-in types
__repr__ และ __str__
หัวข้อที่มีชื่อว่า “__repr__ และ __str__”ทั้งคู่สร้าง string representation แต่เพื่อกลุ่มเป้าหมายต่างกัน:
| Method | เมื่อไหร่ถูกเรียก | วัตถุประสงค์ |
|---|---|---|
__repr__ | repr(obj), interactive shell | Representation ที่ชัดเจนสำหรับนักพัฒนา |
__str__ | str(obj), print(obj) | การแสดงผลที่อ่านง่ายสำหรับมนุษย์ |
ถ้ากำหนดเฉพาะ __repr__ Python จะใช้ __repr__ สำหรับทั้งสองกรณี
Convention สำหรับ __repr__ คือ return string ที่ถ้าส่งผ่าน eval() จะสร้าง object ขึ้นมาใหม่ได้
class Point: def __init__(self, x: float, y: float) -> None: self.x = x self.y = y
def __repr__(self) -> str: return f"Point({self.x}, {self.y})"
def __str__(self) -> str: return f"({self.x}, {self.y})"__eq__ — equality
หัวข้อที่มีชื่อว่า “__eq__ — equality”Python เรียก __eq__ เมื่อเขียน a == b
หากไม่มี __eq__ == จะ fallback ไปใช้ identity comparison (is) — สอง instance แยกกันที่มีข้อมูลเหมือนกันจะไม่เท่ากันเลย
def __eq__(self, other: object) -> bool: if not isinstance(other, Point): return NotImplemented return self.x == other.x and self.y == other.yReturn NotImplemented (ไม่ใช่ False) เมื่อ type ไม่เข้ากัน — เพื่อให้ Python ลอง reflected operation บน operand อีกตัว
__len__ และ __getitem__
หัวข้อที่มีชื่อว่า “__len__ และ __getitem__”Implement __len__ เพื่อรองรับ len(obj)
Implement __getitem__ เพื่อรองรับ obj[index] subscript access
ทั้งคู่รวมกันทำให้ object iterable ผ่าน for loop ด้วย (Python เรียก __getitem__ ด้วย 0, 1, 2, … จนถึง IndexError)
def __len__(self) -> int: return 2
def __getitem__(self, index: int) -> float: return (self.x, self.y)[index]Operator overloading ด้วย __add__
หัวข้อที่มีชื่อว่า “Operator overloading ด้วย __add__”Arithmetic operators map ไปยัง dunder methods:
| Operator | Method |
|---|---|
a + b | a.__add__(b) |
a - b | a.__sub__(b) |
a * b | a.__mul__(b) |
a == b | a.__eq__(b) |
a < b | a.__lt__(b) |
def __add__(self, other: "Vector") -> "Vector": return Vector(self.x + other.x, self.y + other.y)Demo รันได้จริง
หัวข้อที่มีชื่อว่า “Demo รันได้จริง”class Vector: def __init__(self, x: float, y: float) -> None: self.x = x self.y = y
def __repr__(self) -> str: return f"Vector({self.x}, {self.y})"
def __str__(self) -> str: return f"({self.x}, {self.y})"
def __eq__(self, other: object) -> bool: if not isinstance(other, Vector): return NotImplemented return self.x == other.x and self.y == other.y
def __add__(self, other: "Vector") -> "Vector": return Vector(self.x + other.x, self.y + other.y)
def __len__(self) -> int: return 2
def __getitem__(self, index: int) -> float: return (self.x, self.y)[index]
v1 = Vector(1, 2)v2 = Vector(3, 4)print(repr(v1))print(str(v1))print(v1 == Vector(1, 2))print(v1 + v2)print(len(v1))print(v1[0], v1[1])Loading Python runtime (first run only)…