Bài 5. Hàm

Hàm là đoạn mã có tên, viết một lần dùng nhiều lần. Đây là công cụ quan trọng nhất để chương trình gọn và dễ bảo trì.

35 phútCơ bản
Bạn sẽ học được
  • Định nghĩa và gọi hàm
  • Dùng tham số, giá trị mặc định và giá trị trả về
  • Hiểu phạm vi biến cục bộ và toàn cục
  • Viết chú thích mô tả hàm (docstring)
Thuật ngữ cần biết
Hàm (function)
Khối lệnh có tên, nhận đầu vào và có thể trả kết quả.
Tham số (parameter)
Tên biến khai báo trong định nghĩa hàm.
Đối số (argument)
Giá trị thật truyền vào khi gọi hàm.
return
Lệnh trả kết quả về nơi gọi và kết thúc hàm.
Phạm vi (scope)
Vùng mà một biến còn hiệu lực.

Khái niệm và lý thuyết

Hàm là một khối lệnh được đặt tên để dùng lại. Nguyên lý nền tảng của lập trình là chia để trị: chia bài toán lớn thành các bài toán nhỏ, mỗi bài toán nhỏ giải bằng một hàm. Nhờ đó mã ngắn gọn (không lặp lại), dễ kiểm tra (thử từng hàm riêng) và dễ sửa (chỉ sửa ở một chỗ).

Hàm giống một chiếc máy: bạn đưa đầu vào (tham số), máy xử lý và đưa đầu ra (giá trị trả về). Người dùng hàm chỉ cần biết nó làm gì, không cần biết bên trong làm thế nào, gọi là trừu tượng hóa.

Khái niệmGiải thíchVí dụ
Tham sốTên khai báo trong định nghĩadef tong(a, b)
Đối sốGiá trị truyền khi gọitong(3, 4)
Giá trị trả vềKết quả hàm gửi lại bằng returnreturn a + b
Phạm viNơi một biến có hiệu lựcbiến trong hàm là cục bộ

Khi gọi hàm, Python tạm dừng chỗ đang chạy, thực hiện thân hàm, rồi quay lại đúng vị trí gọi với giá trị trả về. Biến tạo trong hàm bị hủy khi hàm kết thúc, nên các hàm không "giẫm chân" lên nhau, đây là lý do nên trao đổi dữ liệu qua tham số và return.

Định nghĩa và gọi hàm

def chao(ten):
    print("Xin chào,", ten)

chao("Lan")
chao("Minh")

Từ khóa def mở đầu, tên hàm, danh sách tham số trong ngoặc, dấu hai chấm, thân hàm thụt lề.

Giá trị trả về và tham số mặc định

def dien_tich_hcn(dai, rong=1):
    """Tính diện tích hình chữ nhật."""
    return dai * rong

print(dien_tich_hcn(5, 3))   # 15
print(dien_tich_hcn(5))      # 5, rong lấy mặc định
print(dien_tich_hcn(rong=2, dai=4))  # truyền theo tên

Một hàm có thể trả nhiều giá trị: return tong, tich (thực chất trả về một bộ).

Phạm vi biến

x = 10          # biến toàn cục
def thu():
    x = 99      # biến cục bộ, không ảnh hưởng x ngoài
    return x
thu()
print(x)        # vẫn 10

Biến tạo trong hàm chỉ tồn tại trong hàm. Nên truyền dữ liệu bằng tham số và nhận kết quả bằng return thay vì dùng biến toàn cục.

Ví dụ: hàm tính BMI và hàm tính thuế

def tinh_bmi(can_nang, chieu_cao):
    return can_nang / (chieu_cao ** 2)

def thue_vat(gia, ty_le=0.08):
    return gia * ty_le

print(tinh_bmi(60, 1.65))
print(thue_vat(100000))        # dùng tỷ lệ mặc định 8%
print(thue_vat(100000, 0.1))   # đổi sang 10%

Tham số có giá trị mặc định (như ty_le=0.08) giúp hàm gọn hơn khi dùng cách phổ biến, mà vẫn linh hoạt khi cần đổi. Một hàm tốt chỉ làm một việc, có tên nói lên việc đó, và trả kết quả bằng return thay vì tự in ra.

Hàm nhỏ giải quyết một việc

def la_nguyen_to(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

print([n for n in range(1, 30) if la_nguyen_to(n)])
Tình huống: Tính tiền hóa đơn

Cửa hàng cần tính tiền sau giảm giá nhiều lần. Viết một hàm dùng chung thay vì chép công thức nhiều chỗ.

def tinh_tien(gia, so_luong, giam=0):
    tong = gia * so_luong
    return tong * (1 - giam)

print(tinh_tien(45000, 3))
print(tinh_tien(45000, 3, giam=0.1))
Mẹo hay

Một hàm nên làm đúng một việc và có tên là động từ: tinh_tong, kiem_tra_email.

Lưu ý

Nếu hàm quên return, kết quả là None. Đừng dùng danh sách rỗng [] làm giá trị mặc định tham số; hãy dùng None.

Thực hành
  1. Viết hàm max2(a, b) trả số lớn hơn.
  2. Viết hàm đổi độ C sang độ F.
  3. Viết hàm kiểm tra năm nhuận, dùng lại ở bài điều kiện.
  4. Viết hàm nhận danh sách điểm, trả điểm trung bình.
Tóm tắt bài học
  • def tạo hàm, return trả kết quả.
  • Tham số có thể có giá trị mặc định, truyền theo vị trí hoặc tên.
  • Biến trong hàm là cục bộ.
  • Chia chương trình thành các hàm nhỏ, tên rõ nghĩa.