Giá trị trả về
Bạn sẽ học được
returnkết thúc hàm và trả giá trị.- Hàm không có
returntrảNone. - Trả nhiều giá trị bằng tuple.
- Thoát sớm và tránh lồng nhánh.
- Khác biệt giữa
printvàreturn— lỗi của người mới.
Khái niệm cốt lõi
return làm hai việc: kết thúc hàm ngay và giao giá trị cho nơi gọi:
def min_max(nums):
return min(nums), max(nums)
low, high = min_max([4, 9, 1])
print(low, high)1 9Dấu phẩy tạo một tuple (1, 9). Phép gán mở gói tuple thành hai biến. Hàm không trả về hai giá trị theo nghĩa kỹ thuật — nó trả một tuple, và Python cho phép viết gọn.
Có thể trả nguyên tuple nếu người gọi muốn:
result = min_max([4, 9, 1])
print(result)(1, 9)Không return thì trả None
Mọi hàm trong Python đều trả một giá trị. Không có return, hoặc return trần, thì giá trị là None:
def chao(name):
print(f"Xin chào {name}")
result = chao("An")
print(result)Xin chào An
Nonechao in ra nhưng không trả gì, nên result là None. Hàm print cũng vậy — nó trả None:
result = print("hello")
print(result)hello
NoneĐây là nguồn gốc của lỗi TypeError: unsupported operand type(s) for +: 'NoneType' and 'str' khi ai đó viết msg = print(...) rồi nối chuỗi.
print khác return
print | return | |
|---|---|---|
| Tác dụng | Hiện ra màn hình | Giao giá trị cho nơi gọi |
| Giá trị hàm | None | Giá trị sau return |
| Dùng lại được | Không | Có |
| Kiểm thử | Phải bắt stdout | So sánh giá trị |
Hàm chỉ print là ngõ cụt: kết quả không dùng được cho tính toán tiếp. Trong xử lý dữ liệu, gần như luôn nên return; chỉ print ở lớp ngoài cùng (CLI, debug).
# Không nên
def tong(nums):
print(sum(nums))
# Nên
def tong(nums):
return sum(nums)
print(tong([1, 2, 3]) * 2)Thoát sớm
return dừng hàm ngay tại dòng đó; mọi lệnh sau không chạy:
def classify(score):
if score < 0:
return "không hợp lệ"
if score >= 90:
return "A"
return "B"
print(classify(-1), classify(95), classify(60))không hợp lệ A BCách viết này phẳng, mỗi điều kiện loại một trường hợp rồi thoát. So với lồng if/else, nó giảm một cấp thụt lề và dễ đọc hơn khi có nhiều điều kiện.
Code sau return trong cùng nhánh là không bao giờ chạy. Đôi khi điều này vô hại, nhưng thường là dấu hiệu logic sai hoặc code chết cần xoá. Editor và lint có thể cảnh báo "unreachable code".
Trả None có chủ đích
Khi hàm không có kết quả hợp lệ, trả None là quy ước:
def doc_diem(raw):
try:
score = float(raw)
except (TypeError, ValueError):
return None
if not 0 <= score <= 100:
return None
return scoreNgười gọi phải kiểm tra:
score = doc_diem("abc")
if score is None:
print("Dữ liệu không hợp lệ")
else:
print(f"Điểm: {score}")Trả None tách biệt với trả 0 — điều mà return 0 cho trường hợp lỗi sẽ làm mất. Nếu lỗi cần thông tin chi tiết hơn (None không nói lý do), có thể trả tuple (value, error) hoặc ném exception. Với bài toán nhỏ, None là đủ.
Hàm là giá trị
Trong Python, hàm là đối tượng, nên có thể trả hàm từ hàm khác:
def tao_bo_dem():
count = 0
def dem():
nonlocal count
count += 1
return count
return dem
bo_dem = tao_bo_dem()
print(bo_dem(), bo_dem())1 2Đây là closure. Hàm dem được trả ra ngoài vẫn giữ biến count của lần gọi tao_bo_dem. Mẫu này hữu ích cho state cục bộ mà không cần class.
Thực hành
- Viết
min_maxtrả tuple, unpack thành hai biến. - Viết hàm chỉ
print, gán kết quả và kiểm traNone. - Viết
classifyvới thoát sớm cho ba trường hợp. - Thêm
returngiữa hàm và quan sát các dòng sau không chạy. - Viết
doc_diemtrảNonekhi lỗi, xử lý ở nơi gọi. - Viết hàm trả về một hàm đếm, gọi ba lần.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
Kết quả là None | Hàm không return | Thêm return |
TypeError với NoneType | Gán kết quả print | Trả giá trị thay vì in |
| Chỉ nhận được giá trị đầu | return dừng hàm | Gom nhiều giá trị vào tuple/list |
Code sau return không chạy | return đã thoát | Sắp lại thứ tự hoặc bỏ code chết |
ValueError khi unpack | Số phần tử không khớp | Kiểm tra tuple trả về |
Không phân biệt lỗi với 0 | Trả 0 khi lỗi | Trả None hoặc ném exception |
Hàm trả None ngoài ý muốn | Nhánh if không có return | Rà mọi nhánh |
Tóm tắt
returnkết thúc hàm và trả giá trị; không có thì trảNone.- Nhiều giá trị thực chất là một tuple, unpack được.
printchỉ hiện;returnmới cho dùng lại và kiểm thử.- Thoát sớm làm code phẳng và rõ.
- Dùng
Nonecho "không có kết quả", đừng dùng0— và luôn kiểm tra ở nơi gọi.
Use ← → to move between lessons