Methods
— Hành Động Của Object
Class không chỉ lưu dữ liệu — nó còn biết làm những việc cụ thể. Đó chính là sức mạnh của Methods!
Bạn đã biết từ Chapter 1
Chapter 2 xây lên trên nền đó: thêm methods (phương thức) để object không chỉ có dữ liệu mà còn biết làm việc!
Method — Hành động của Object
Nếu thuộc tính (attribute) là những thứ object có, thì method là những thứ object có thể làm. Method về bản chất là hàm (def) được định nghĩa bên trong một Class.
Robot biết: đi, nói chuyện, nhặt đồ (methods).
Thiếu method thì object chỉ là… "đống dữ liệu" thôi!
self.ten, self.tuoi
Những thứ object LÀM ĐƯỢCchao(), tinh_diem(), chay()
Lưu dữ liệu — là biến
Xử lý logic — là hàm (có self)
Cú pháp — Method luôn có self
Method được khai báo như hàm thông thường, nhưng luôn có tham số đầu tiên là self — đây là điểm khác biệt duy nhất!
class HocSinh: def __init__(self, ten, diem): self.ten = ten self.diem = diem ① def chao(self): ← ② tên method — không tham số ngoài self print(f"Chào! Tôi là {self.ten}") ← ③ dùng self để lấy thuộc tính ④ def xep_loai(self): ← method thứ hai if self.diem >= 8: return "Giỏi 🌟" return "Khá ✅"
# Gọi method bằng dấu chấm (.) — giống truy cập thuộc tính nam = HocSinh("Nam", 8.5) nam.chao() # Gọi method — không cần truyền self! loai = nam.xep_loai() print(loai)
Giỏi 🌟
nam.chao(), Python tự động truyền nam vào tham số self. Bạn không cần tự làm điều này!
Bí mật của self — Python làm điều kỳ diệu!
Nhiều bạn thắc mắc: "Tại sao gọi nam.chao() không cần truyền self?" — Python xử lý điều đó ngầm bên trong!
class ViDu: def __init__(self, gia_tri): self.gia_tri = gia_tri def hien_thi(self): print(f"self là: {self}") print(f"gia_tri: {self.gia_tri}") a = ViDu(42) b = ViDu(99) a.hien_thi() # self = a print("---") b.hien_thi() # self = b (khác rồi!)
gia_tri: 42
---
self là: <__main__.ViDu object at 0x...>
gia_tri: 99
Hai lần gọi cùng một method hien_thi() nhưng self khác nhau — self chính là object nào đang gọi method đó!
Truyền tham số vào Method
Method hoàn toàn có thể nhận thêm tham số — chỉ cần thêm vào sau self:
class TaiKhoanNganHang: def __init__(self, chu_tk, so_du=0): self.chu_tk = chu_tk self.so_du = so_du self.lich_su = [] def nap_tien(self, so_tien): ← tham số ngoài self self.so_du += so_tien self.lich_su.append(f"+{so_tien:,}đ") print(f"✅ Nạp {so_tien:,}đ — Số dư: {self.so_du:,}đ") def rut_tien(self, so_tien): ← tham số ngoài self if so_tien > self.so_du: print("❌ Số dư không đủ!") return self.so_du -= so_tien self.lich_su.append(f"-{so_tien:,}đ") print(f"💸 Rút {so_tien:,}đ — Còn lại: {self.so_du:,}đ") def xem_lich_su(self): ← không tham số ngoài print(f"\n📋 Lịch sử TK của {self.chu_tk}:") for gd in self.lich_su: print(f" {gd}") # Sử dụng tk = TaiKhoanNganHang("Nguyễn Văn Nam", 500_000) tk.nap_tien(200_000) tk.rut_tien(100_000) tk.rut_tien(700_000) # thử rút quá số dư tk.xem_lich_su()
💸 Rút 100,000đ — Còn lại: 600,000đ
❌ Số dư không đủ!
📋 Lịch sử TK của Nguyễn Văn Nam:
+200,000đ
-100,000đ
Method có thể gọi method khác trong cùng Class
Bên trong một method, bạn dùng self.ten_method() để gọi method khác của cùng object:
class HocSinh: def __init__(self, ten, ds_diem): self.ten = ten self.ds_diem = ds_diem def tinh_tb(self): return sum(self.ds_diem) / len(self.ds_diem) def xep_loai(self): tb = self.tinh_tb() ← gọi method khác qua self! if tb >= 8: return "Giỏi 🌟" elif tb >= 6.5: return "Khá ✅" else: return "Trung Bình 📝" def bao_cao(self): tb = self.tinh_tb() ← dùng lại method khác loai = self.xep_loai() ← và method khác nữa! print(f"┌─── Học Bạ ───────────") print(f"│ Tên : {self.ten}") print(f"│ TB : {tb:.1f}") print(f"│ Loại : {loai}") print(f"└──────────────────────") nam = HocSinh("Nguyễn Nam", [8, 9, 7.5, 8.5, 10]) nam.bao_cao()
│ Tên : Nguyễn Nam
│ TB : 8.6
│ Loại : Giỏi 🌟
└──────────────────────
bao_cao() không tính lại từ đầu — nó gọi tinh_tb() và xep_loai() đã có sẵn. Đây chính là sức mạnh của OOP: mỗi method làm một việc, kết hợp lại thành hệ thống!
Python có 3 loại Method — Ch.2 học loại chính!
- Loại phổ biến nhất
- Tham số đầu là
self - Truy cập được thuộc tính object
- Đang học ở Chapter 2
- Dùng
@classmethod - Tham số đầu là
cls - Truy cập được class, không phải object
- Học ở Chapter 7
- Dùng
@staticmethod - Không có self hay cls
- Hàm tiện ích trong class
- Học ở Chapter 7
Quy tắc vàng khi viết Method
tinh_tong(), xep_loai()nap_tien(), in_bao_cao(), cap_nhat_diem()xu_ly(), ham1(), lam_viec() — không biết làm gì!self ở tham số đầu — Python sẽ báo lỗi ngay!Xây dựng Class QuanLyLop
Kết hợp thuộc tính và nhiều method để tạo hệ thống quản lý lớp học hoàn chỉnh:
class QuanLyLop: def __init__(self, ten_lop): self.ten_lop = ten_lop self.hoc_sinh = {} # {ten: [diem]} def them_hoc_sinh(self, ten): if ten not in self.hoc_sinh: self.hoc_sinh[ten] = [] print(f"➕ Đã thêm: {ten}") else: print(f"⚠️ {ten} đã có trong lớp!") def nhap_diem(self, ten, diem): if ten in self.hoc_sinh: self.hoc_sinh[ten].append(diem) else: print(f"❌ Không tìm thấy: {ten}") def _tinh_tb(self, ten): ← method "nội bộ" ds = self.hoc_sinh[ten] return round(sum(ds) / len(ds), 1) if ds else 0 def bao_cao_lop(self): print(f"\n{'═'*36}") print(f" 📋 BÁO CÁO LỚP {self.ten_lop.upper()}") print(f"{'─'*36}") for ten, ds in self.hoc_sinh.items(): tb = self._tinh_tb(ten) ← gọi method khác xl = "Giỏi" if tb >= 8 else "Khá" if tb >= 6.5 else "TB" print(f" {ten:12} TB: {tb:4} [{xl}]") print(f"{'═'*36}\n") # ── Sử dụng ───────────────────────────── lop8a = QuanLyLop("8A") for hs in ["Nam", "Lan", "Bình"]: lop8a.them_hoc_sinh(hs) lop8a.nhap_diem("Nam", 8.5); lop8a.nhap_diem("Nam", 9.0) lop8a.nhap_diem("Lan", 7.0); lop8a.nhap_diem("Lan", 6.5) lop8a.nhap_diem("Bình", 9.5); lop8a.nhap_diem("Bình", 8.0) lop8a.bao_cao_lop()
➕ Đã thêm: Lan
➕ Đã thêm: Bình
════════════════════════════════════
📋 BÁO CÁO LỚP 8A
────────────────────────────────────
Nam TB: 8.8 [Giỏi]
Lan TB: 6.8 [Khá]
Bình TB: 8.8 [Giỏi]
════════════════════════════════════
_tinh_tb() — dấu gạch dưới đầu!
Quy ước _ten_method có nghĩa là "method nội bộ — chỉ dùng trong class". Bạn sẽ học sâu hơn về điều này ở Chapter 3: Encapsulation!
🧩 Kiểm tra nhanh!
Ôn lại kiến thức Chapter 2 — Methods!
→ Nằm trong class và có tham số self đầu tiên
→ object.ten_method(tham_so)
→ self.ten_method_khac()
→ Có — method chỉ in ra màn hình không cần return