Hàm (function) trong Python: Cách tạo và gọi hàm
Hàm (function) là cách đóng gói một đoạn code để tái sử dụng. Thay vì copy-paste lặp đi lặp lại, bạn định nghĩa hàm một lần — rồi gọi nó ở bất kỳ đâu cần dùng.
Tại sao cần hàm?
Nhìn ví dụ này sẽ thấy rõ vấn đề:
# Không dùng hàm — code lặp lại cho mỗi học sinh
diem1 = 8.5
if diem1 >= 8.0:
print(f"Điểm {diem1}: Giỏi")
diem2 = 6.5
if diem2 >= 6.5:
print(f"Điểm {diem2}: Khá")
# ... lặp lại cho 30 học sinh nữa
# Dùng hàm — viết một lần, gọi bao nhiêu lần cũng được
def xep_loai(diem):
if diem >= 8.0:
return "Giỏi"
elif diem >= 6.5:
return "Khá"
else:
return "Trung bình"
print(xep_loai(8.5)) # Giỏi
print(xep_loai(6.5)) # Khá
print(xep_loai(5.0)) # Trung bình
Đây chính là nguyên tắc DRY — Don't Repeat Yourself. Khi cần sửa logic xếp loại, bạn chỉ sửa đúng một chỗ, không phải tìm và sửa 30 chỗ rải rác.
Cú pháp định nghĩa hàm
def tên_hàm(tham_số_1, tham_số_2):
"""Mô tả ngắn hàm này làm gì (không bắt buộc nhưng nên có)"""
# code xử lý
return kết_quả # tùy chọn
Ví dụ đơn giản nhất — hàm không nhận tham số, không trả về gì:
def chao_mung():
print("Xin chào! Chào mừng đến với VietCode!")
chao_mung() # Xin chào! Chào mừng đến với VietCode!
chao_mung() # Gọi bao nhiêu lần cũng được
Các kiểu tham số
Tham số bắt buộc
def chao_ten(ten):
return f"Xin chào, {ten}!"
print(chao_ten("Minh")) # Xin chào, Minh!
print(chao_ten("Lan")) # Xin chào, Lan!
# chao_ten() → TypeError: thiếu đối số bắt buộc
Tham số mặc định
Khi gọi hàm mà không truyền giá trị, Python dùng giá trị mặc định đã khai báo:
def tao_email(ten, domain="gmail.com"):
return f"{ten.lower()}@{domain}"
print(tao_email("minh")) # minh@gmail.com
print(tao_email("lan", "yahoo.com")) # lan@yahoo.com
*args — số lượng đối số không cố định
Dùng khi không biết trước sẽ truyền vào bao nhiêu giá trị:
def tinh_tong(*so):
return sum(so)
print(tinh_tong(1, 2, 3)) # 6
print(tinh_tong(10, 20, 30, 40)) # 100
**kwargs — đối số có tên, số lượng linh động
def tao_profile(**thong_tin):
for truong, gia_tri in thong_tin.items():
print(f"{truong}: {gia_tri}")
tao_profile(ten="Nguyễn Minh", tuoi=22, thanh_pho="Hà Nội")
# ten: Nguyễn Minh
# tuoi: 22
# thanh_pho: Hà Nội
Câu lệnh return
Hàm có thể trả về một giá trị, hoặc trả về nhiều giá trị cùng lúc dưới dạng tuple:
def tinh_bmi(can_nang, chieu_cao):
bmi = can_nang / (chieu_cao ** 2)
if bmi < 18.5:
tinh_trang = "Thiếu cân"
elif bmi < 25:
tinh_trang = "Bình thường"
elif bmi < 30:
tinh_trang = "Thừa cân"
else:
tinh_trang = "Béo phì"
return bmi, tinh_trang # trả về tuple
ket_qua_bmi, ket_qua_loai = tinh_bmi(65, 1.70)
print(f"BMI: {ket_qua_bmi:.1f} — {ket_qua_loai}")
Ví dụ thực tế hơn — phân tích điểm cả lớp chỉ với một hàm:
def phan_tich_diem(ds):
return max(ds), min(ds), sum(ds) / len(ds)
diem = [8.5, 6.0, 9.2, 7.8]
cao, thap, tb = phan_tich_diem(diem)
print(f"Cao nhất: {cao}, Thấp nhất: {thap}, Trung bình: {tb:.2f}")
Lambda — hàm viết gọn trong một dòng
Lambda phù hợp cho những logic đơn giản, thường dùng kết hợp với sorted(), map(), filter():
nhan_doi = lambda x: x * 2
print(nhan_doi(5)) # 10
# Sắp xếp danh sách sinh viên theo điểm
sinh_vien = [
{"ten": "Minh", "diem": 8.5},
{"ten": "Lan", "diem": 9.2},
{"ten": "Nam", "diem": 7.8}
]
sap_xep = sorted(sinh_vien, key=lambda sv: sv["diem"], reverse=True)
# Kết quả: Lan (9.2) → Minh (8.5) → Nam (7.8)
Nếu logic phức tạp hơn một dòng, dùng def thông thường cho dễ đọc hơn.
Scope — biến local và global
Biến khai báo bên trong hàm chỉ tồn tại trong hàm đó, không ảnh hưởng ra ngoài:
x = 10 # biến global
def thu_nghiem():
x = 20 # biến local — chỉ sống trong hàm này
print(x) # 20
thu_nghiem()
print(x) # 10 — biến global giữ nguyên
Các hàm built-in hay dùng
Python có sẵn nhiều hàm tiện ích, không cần import thêm:
print(abs(-10)) # 10
print(max(1, 5, 3)) # 5
print(min(1, 5, 3)) # 1
print(sum([1, 2, 3])) # 6
print(len("hello")) # 5
print(sorted([3,1,2])) # [1, 2, 3]
print(range(5)) # range(0, 5)
Kết luận
Hàm là nền tảng để viết Python sạch và dễ bảo trì. Nắm chắc def, return, các kiểu tham số và lambda là đủ để xử lý hầu hết tình huống thực tế. Bước tiếp theo là tìm hiểu cách tổ chức nhiều hàm vào module và class.