Các Phương Thức Dunder/Magic/Special trong Python
Trong Python, các phương thức Dunder (viết tắt của Double Under), còn được gọi là phương thức Magic hoặc phương thức Special, là những phương thức có tên được bao quanh bởi hai dấu gạch dưới (ví dụ: __init__
, __str__
, __add__
). Các phương thức này được Python tự động gọi khi một số hoạt động nhất định xảy ra trên đối tượng.
Các phương thức Dunder cho phép các lớp trong Python có thể tương tác tự nhiên với cú pháp và cấu trúc ngôn ngữ Python, giúp các đối tượng hoạt động giống như các kiểu dữ liệu cơ bản.
Dưới đây là một số phương thức Dunder phổ biến và cách chúng hoạt động.
1. __init__(self, ...)
– Phương Thức Khởi Tạo
Phương thức __init__
là phương thức khởi tạo, được gọi khi một đối tượng của lớp được tạo ra. Nó giúp khởi tạo các thuộc tính của đối tượng khi đối tượng được tạo.
Ví dụ:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Tạo đối tượng
person = Person("Anh", 25)
print(person.name) # Output: Anh
print(person.age) # Output: 25
Phương thức __init__
không trả về giá trị, mà chỉ khởi tạo các thuộc tính của đối tượng.
2. __str__(self)
– Phương Thức Chuỗi (String Representation)
Phương thức __str__
trả về một chuỗi để mô tả đối tượng dưới dạng dễ đọc. Nó được gọi tự động khi bạn sử dụng hàm print()
hoặc str()
trên một đối tượng.
Ví dụ:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person({self.name}, {self.age})"
# Tạo đối tượng
person = Person("Anh", 25)
print(person) # Output: Person(Anh, 25)
3. __repr__(self)
– Phương Thức Biểu Diễn (Representation)
Phương thức __repr__
trả về chuỗi biểu diễn của đối tượng sao cho nó có thể được sử dụng để tái tạo đối tượng. Nó được gọi khi bạn sử dụng hàm repr()
hoặc khi kiểm tra đối tượng trong môi trường tương tác.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person({self.name!r}, {self.age!r})"
person = Person("Anh", 25)
print(repr(person)) # Output: Person('Anh', 25)
4. __len__(self)
– Phương Thức Chiều Dài
Phương thức __len__
trả về độ dài của đối tượng. Nó được gọi khi sử dụng hàm len()
.
Ví dụ:
class MyList:
def __init__(self, elements):
self.elements = elements
def __len__(self):
return len(self.elements)
my_list = MyList([1, 2, 3, 4])
print(len(my_list)) # Output: 4
5. __getitem__(self, key)
– Truy Cập Phần Tử
Phương thức __getitem__
được gọi khi bạn truy cập một phần tử trong đối tượng bằng cú pháp obj[key]
.
Ví dụ:
class MyList:
def __init__(self, elements):
self.elements = elements
def __getitem__(self, index):
return self.elements[index]
my_list = MyList([1, 2, 3, 4])
print(my_list[2]) # Output: 3
6. __setitem__(self, key, value)
– Gán Giá Trị Cho Phần Tử
Phương thức __setitem__
được gọi khi bạn gán giá trị cho một phần tử trong đối tượng với cú pháp obj[key] = value
.
class MyList:
def __init__(self, elements):
self.elements = elements
def __setitem__(self, index, value):
self.elements[index] = value
my_list = MyList([1, 2, 3, 4])
my_list[2] = 100
print(my_list.elements) # Output: [1, 2, 100, 4]
7. __delitem__(self, key)
– Xóa Phần Tử
Phương thức __delitem__
được gọi khi bạn xóa một phần tử trong đối tượng với cú pháp del obj[key]
.
class MyList:
def __init__(self, elements):
self.elements = elements
def __delitem__(self, index):
del self.elements[index]
my_list = MyList([1, 2, 3, 4])
del my_list[2]
print(my_list.elements) # Output: [1, 2, 4]
8. __add__(self, other)
– Phép Cộng
Phương thức __add__
định nghĩa hành vi của phép cộng (+
) giữa hai đối tượng.
Ví dụ:
class Number:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Number(self.value + other.value)
def __str__(self):
return str(self.value)
a = Number(10)
b = Number(5)
c = a + b
print(c) # Output: 15
9. __call__(self, ...)
– Biến Đối Tượng Thành Hàm
Phương thức __call__
cho phép một đối tượng hoạt động như một hàm, có nghĩa là bạn có thể “gọi” một đối tượng như gọi một hàm.
class Greeter:
def __init__(self, name):
self.name = name
def __call__(self):
return f"Hello, {self.name}!"
greeter = Greeter("Anh")
print(greeter()) # Output: Hello, Anh!
10. __eq__(self, other)
– So Sánh Bằng (==
)
Phương thức __eq__
định nghĩa hành vi của toán tử so sánh ==
giữa hai đối tượng.
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("Anh", 25)
p2 = Person("Anh", 25)
print(p1 == p2) # Output: True
11. __lt__(self, other)
– So Sánh Nhỏ Hơn (<
)
Phương thức __lt__
định nghĩa hành vi của toán tử so sánh nhỏ hơn <
.
<pre class="wp-block-syntaxhighlighter-code">class Number:
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
a = Number(10)
b = Number(5)
print(a < b) # Output: False</pre>
12. __contains__(self, item)
– Kiểm Tra Sự Tồn Tại
Phương thức __contains__
được gọi khi bạn kiểm tra xem một đối tượng có tồn tại trong một container với cú pháp item in obj
.
class MyList:
def __init__(self, elements):
self.elements = elements
def __contains__(self, item):
return item in self.elements
my_list = MyList([1, 2, 3, 4])
print(3 in my_list) # Output: True
13. __iter__(self)
và __next__(self)
– Duyệt Qua Các Đối Tượng
Phương thức __iter__
và __next__
được sử dụng để biến đối tượng thành iterable (có thể duyệt qua các phần tử).
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
self.current += 1
return self.current - 1
for num in MyRange(1, 5):
print(num)
# Output: 1, 2, 3, 4
14. Kết Luận
Các phương thức Dunder/Magic/Special trong Python giúp bạn tùy chỉnh hành vi của các đối tượng khi sử dụng các toán tử, phương thức tích hợp, hoặc thao tác với các cấu trúc ngôn ngữ. Việc sử dụng các phương thức này giúp viết mã Python ngắn gọn, dễ hiểu hơn và dễ dàng mở rộng các lớp theo nhu cầu riêng của bạn.