Bài học theo mô-đun (3/4)
Các phương pháp đặc biệt (dunder)
Các phương pháp đặc biệt (được gọi là các phương pháp dunder vì chúng bắt đầu và kết thúc
với dấu gạch dưới kép: __name__) là những cái móc cho phép các đối tượng của bạn
tích hợp với ngôn ngữ: trình bày văn bản, so sánh với ==,
hỗ trợ cho len(), in, toán tử, v.v.
Bạn đã sử dụng một tài khoản: __init__.
__str__ và __repr__
Họ kiểm soát những gì xuất hiện với print() và trong REPL.
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Punto({self.x}, {self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
p = Punto(3, 4)
str(p) # '(3, 4)' — per umani
repr(p) # 'Punto(3, 4)' — per debugger / dev
print(p) # '(3, 4)'
p # Punto(3, 4) in REPL → repr
[p, p] # [Punto(3, 4), Punto(3, 4)] — sempre repr nei contenitoriNếu bạn chỉ xác định __repr__, Python cũng sử dụng nó làm dự phòng cho
__str__.
__eq__: xác định lại ==
Theo mặc định a == b so sánh mã định danh của các đối tượng (is), chứ không phải
nội dung của chúng. Để so sánh cấu trúc, hãy xác định __eq__:
class Punto:
def __init__(self, x, y):
self.x, self.y = x, y
def __eq__(self, other):
if not isinstance(other, Punto):
return NotImplemented
return (self.x, self.y) == (other.x, other.y)
Punto(1, 2) == Punto(1, 2) # True
Punto(1, 2) == Punto(3, 4) # FalseTrả về NotImplemented (một từ khóa đặc biệt, không phải False!) khi loại
không thể so sánh được là cách làm đúng: Python sau đó sẽ thử với
toán hạng khác __eq__.
__len__: hỗ trợ cho len()
class Cesto:
def __init__(self):
self.frutti = []
def __len__(self):
return len(self.frutti)
c = Cesto()
c.frutti.append("mela")
len(c) # 1
bool(c) # True (len > 0)Bằng cách xác định __len__, bạn cũng nhận được boolean miễn phí: một đối tượng
với len() == 0 trở thành giả.
Những điều ngớ ngẩn hữu ích khác (tổng quan)
__add__(self, other)→ định nghĩa lại+__lt__,__le__,__gt__,__ge__→ toán tử so sánh__contains__(self, item)→ hỗ trợitem in self__iter__+__next__→ làm cho đối tượng có thể lặp lại__getitem__(self, key)→ hỗ trợself[key]__hash__→ bắt buộc phải là khóa chính tả/phần tử tập hợp
Đến lượt bạn
Xác định `Tiền` bằng __init__(bản thân, số tiền, tiền tệ) và __str__ trả về `f'{amount} {currency}'`. Tạo `s = Money(42, 'EUR')` và đánh giá `str(s)`.
Hiển thị gợi ý
chuỗi f trong __str__.
Giải pháp khả dụng sau 3 lần thử
Xem lại bài tập
Xác định `Pair` với __init__(self, a, b) và __eq__ dựa trên so sánh cấu trúc của (a, b). Đánh giá `Cặp(1, 2) == Cặp(1, 2)`.
Hiển thị gợi ý
So sánh các bộ dữ liệu (self.a, self.b) == (other.a, other.b).
Giải pháp khả dụng sau 3 lần thử
Thử thách bổ sung
Xác định một lớp \`Book\` với một hàm tạo lấy \`title\` và \`author\`. Xác định phương thức đặc biệt \`__str__(self)\` để nó trả về chuỗi \`"Title by Author"\` (ví dụ \`'1984 by George Orwell'\`). Khởi tạo một cuốn sách và đánh giá \`str(book)\`.
Hiển thị gợi ý
Sử dụng f"{self.title} của {self.author}" bên trong def __str__(self):.
Giải pháp khả dụng sau 3 lần thử