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)__next__(self) – Duyệt Qua Các Đối Tượng

Phương thức __iter____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.