Trong bài này chúng ta sẽ cùng tìm hiểu hàm trong Python: hàm là gì, cách khai báo và gọi hàm, tham số mặc định, phạm vi biến trong hàm và cách truyền số lượng tham số tùy ý.
Hàm giống như một cái máy xay sinh tố: bạn bỏ nguyên liệu vào (tham số), máy xử lý bên trong, rồi trả ra cốc sinh tố (giá trị trả về). Mỗi lần muốn xay chỉ cần bấm nút, không phải lắp lại cái máy từ đầu. Viết code cũng vậy, đoạn nào dùng nhiều lần thì gói vào hàm nhé.
Giới thiệu về hàm trong Python
Ngôn ngữ nào cũng có hàm, và Python cũng vậy. Hàm (function) là một khối code thực hiện một việc cụ thể và có thể gọi lại nhiều lần. Dùng hàm giúp code ngắn hơn, dễ đọc hơn, và khi cần sửa thì chỉ sửa một chỗ.
Để định nghĩa hàm, chúng ta dùng từ khóa def, theo sau là tên hàm, danh sách tham số trong ngoặc và dấu hai chấm. Các lệnh của hàm viết thụt vào bên dưới. Nếu hàm cần trả kết quả về thì dùng return.

Ví dụ một hàm tính tổng hai số:
def tinh_tong(a, b):
tong = a + b
return tong
Gọi hàm bằng cách truyền 2 số vào, giá trị trả về được gán cho một biến:
tong_cua_5_va_7 = tinh_tong(5, 7) print(tong_cua_5_va_7) # sẽ in ra 12
Ngoài def, Python còn có hàm vô danh lambda để định nghĩa nhanh các hàm ngắn chỉ có một biểu thức. Ví dụ hàm tính bình phương:
square = lambda x: x ** 2 print(square(5)) # sẽ in ra 25
Cách khai báo hàm trong Python
Cú pháp khai báo hàm:
def ten_ham(param):
# code
Chú thích:
-
ten_ham: tên hàm, theo đúng quy tắc định danh: không bắt đầu bằng số, không chứa ký tự đặc biệt.
-
param: các tham số truyền vào hàm, cách nhau bằng dấu phẩy. Hàm không cần tham số thì để trống cặp ngoặc.

Ví dụ: viết hàm tìm số lớn nhất trong một danh sách.
def tim_so_lon_nhat(danh_sach):
so_lon_nhat = danh_sach[0]
for so in danh_sach:
if so > so_lon_nhat:
so_lon_nhat = so
return so_lon_nhat
Hàm tên là tim_so_lon_nhat, nhận một tham số danh_sach. Đầu tiên gán tạm so_lon_nhat bằng phần tử đầu tiên. Sau đó duyệt qua từng số, gặp số nào lớn hơn thì cập nhật lại. Duyệt hết thì return kết quả.
Gọi thử hàm:
danh_sach = [1, 5, 3, 9, 2] so_lon_nhat = tim_so_lon_nhat(danh_sach) print(so_lon_nhat) # 9
Kết quả in ra là 9, số lớn nhất trong danh sách [1, 5, 3, 9, 2].
Lưu ý: Để ý lệnh return phải thẳng hàng với for, không được thụt vào trong vòng lặp. Nếu thụt vào, hàm sẽ return ngay ở vòng đầu tiên và luôn trả về phần tử đầu của danh sách. Đây là lỗi rất khó phát hiện vì code vẫn chạy, chỉ là ra kết quả sai.
Làm sao để gọi hàm trong Python?
Gọi hàm bằng tên hàm, theo sau là cặp ngoặc chứa các đối số (argument) truyền vào.

Ví dụ 1: dùng lại hàm tinh_tong ở trên.
def tinh_tong(a, b):
tong = a + b
return tong
Truyền vào 2 số, lưu giá trị trả về vào một biến:
x = 3 y = 4 z = tinh_tong(x, y) print(z) # 7
Hàm tinh_tong được gọi với 2 đối số x và y, kết quả 3 + 4 = 7 được lưu vào z rồi in ra.
Ví dụ 2: dùng lại hàm tim_so_lon_nhat.
def tim_so_lon_nhat(danh_sach):
so_lon_nhat = danh_sach[0]
for so in danh_sach:
if so > so_lon_nhat:
so_lon_nhat = so
return so_lon_nhat
Truyền vào một danh sách và lưu kết quả:
a = [1, 5, 3, 9, 2] b = tim_so_lon_nhat(a) print(b) # 9
Biến b nhận giá trị 9, là số lớn nhất trong danh sách a.
Tham số mặc định cho hàm trong Python
Python cho phép đặt giá trị mặc định cho tham số. Khi gọi hàm mà không truyền giá trị cho tham số đó, giá trị mặc định sẽ được dùng.
Cú pháp:
def ten_ham(tham_so_1, tham_so_2=default_value):
# code thực hiện công việc của hàm
default_value là giá trị mặc định của tham_so_2. Nếu lúc gọi hàm không truyền tham_so_2 thì nó lấy giá trị này.
Ví dụ: in thông tin một người gồm tên, tuổi và địa chỉ. Nếu không có địa chỉ thì in “Không có địa chỉ”.
def in_thong_tin(ten, tuoi, dia_chi="Không có địa chỉ"):
print("Tên:", ten)
print("Tuổi:", tuoi)
print("Địa chỉ:", dia_chi)
# Gọi hàm với giá trị địa chỉ được truyền vào
in_thong_tin("Anh", 20, "Hà Nội")
# Gọi hàm mà không truyền giá trị cho địa chỉ
in_thong_tin("Bình", 25)
Kết quả:
Tên: Anh Tuổi: 20 Địa chỉ: Hà Nội Tên: Bình Tuổi: 25 Địa chỉ: Không có địa chỉ
Lưu ý: Tham số có giá trị mặc định phải đứng sau các tham số không có giá trị mặc định. Nếu đặt tham số dia_chi có giá trị mặc định lên trước ten và tuoi thì Python sẽ báo SyntaxError ngay.
Phạm vi của biến trong hàm
Phạm vi (scope) của biến cho biết biến đó được dùng ở đâu. Biến khai báo bên trong hàm là biến cục bộ, chỉ dùng được trong hàm đó. Biến khai báo ngoài hàm là biến toàn cục, dùng được ở mọi nơi trong chương trình.
Nếu cố truy cập biến cục bộ từ bên ngoài hàm, Python sẽ báo lỗi NameError.
Ví dụ: hàm tinh_tong tính tổng hai số và in ra kết quả.
def tinh_tong(a, b):
tong = a + b
print("Tổng là:", tong)
tinh_tong(2, 3)
Kết quả:
Tổng là: 5
Biến tong được tạo bên trong hàm nên là biến cục bộ. Bây giờ thử gọi hàm xong rồi in tong ở bên ngoài:
def tinh_tong(a, b):
tong = a + b
return tong
tinh_tong(2, 3)
print("Tổng là:", tong)
Lỗi:
NameError: name 'tong' is not defined
Biến tong chỉ tồn tại trong lúc hàm tinh_tong đang chạy, hàm chạy xong là biến biến mất. Bên ngoài hàm không có biến nào tên tong nên Python báo lỗi. Muốn dùng kết quả ở ngoài thì phải hứng giá trị return vào một biến, ví dụ ket_qua = tinh_tong(2, 3).
Truyền vô số tham số vào hàm trong Python
Đôi khi bạn không biết trước sẽ truyền bao nhiêu đối số vào hàm, ví dụ hàm tính tổng của 2 số, 5 số hay 100 số. Python cho phép làm việc này bằng cách đặt dấu * trước tên tham số, thường đặt tên là *args.
Khi đó tất cả đối số truyền vào sẽ được gom thành một tuple, và chúng ta dùng vòng lặp để duyệt qua.
Ví dụ: hàm tong tính tổng tất cả các số được truyền vào:
def tong(*args):
s = 0
for i in args:
s += i
return s
Gọi hàm tong với số lượng đối số bất kỳ:
print(tong(1, 2, 3, 4, 5)) # Kết quả: 15 print(tong(2, 4, 6, 8, 10)) # Kết quả: 30 print(tong()) # Kết quả: 0
Truyền 5 số, 5 số khác, hay không truyền gì, hàm đều chạy được. Không truyền gì thì args là tuple rỗng, vòng lặp không chạy và hàm trả về 0.
Tổng kết
Hàm là công cụ cơ bản nhất để tổ chức code. Đoạn nào lặp lại từ 2 lần trở lên thì nên tách ra thành hàm, code sẽ gọn và dễ sửa hơn rất nhiều.
Hi vọng bài viết này có ích với bạn, hẹn gặp lại trong bài tiếp theo về module trong Python.

