Skip to content

🔗 14.2 Tham số và giá trị trả về

📖 Giới thiệu

Tham số (parameters) và giá trị trả về (return values) là hai khái niệm cốt lõi của function. Chúng giúp function linh hoạt, có thể tái sử dụng và giao tiếp với phần code khác một cách hiệu quả.

INFO

Function nhận input qua tham số và trả output qua giá trị trả về

📥 Các loại tham số

🔢 Tham số vị trí (Positional Arguments)

python
def tinh_dien_tich_hinh_chu_nhat(chieu_dai, chieu_rong):
    """Tính diện tích hình chữ nhật"""
    dien_tich = chieu_dai * chieu_rong
    print(f"📐 Hình chữ nhật {chieu_dai}x{chieu_rong}")
    print(f"📊 Diện tích: {dien_tich} m²")
    return dien_tich

# Gọi function với tham số vị trí
dt1 = tinh_dien_tich_hinh_chu_nhat(5, 3)
dt2 = tinh_dien_tich_hinh_chu_nhat(7, 4)

print(f"\nTổng diện tích: {dt1 + dt2} m²")

def gioi_thieu_ban_than(ten, tuoi, thanh_pho):
    """Giới thiệu thông tin cá nhân"""
    return f"Xin chào! Tôi là {ten}, {tuoi} tuổi, đến từ {thanh_pho}."

# Thứ tự tham số rất quan trọng
gt1 = gioi_thieu_ban_than("An", 20, "Hà Nội")
gt2 = gioi_thieu_ban_than("Bình", 22, "TP.HCM")

print(f"\n👋 {gt1}")
print(f"👋 {gt2}")

🏷️ Tham số từ khóa (Keyword Arguments)

python
def tao_profile_hoc_sinh(ten, tuoi, lop, diem_tb, que_quan="Chưa cập nhật"):
    """Tạo profile học sinh với thông tin chi tiết"""
    profile = {
        "ten": ten,
        "tuoi": tuoi, 
        "lop": lop,
        "diem_tb": diem_tb,
        "que_quan": que_quan
    }
    return profile

# Gọi với keyword arguments (không cần theo thứ tự)
hs1 = tao_profile_hoc_sinh(ten="Chi", lop="10A1", tuoi=16, diem_tb=8.5)
hs2 = tao_profile_hoc_sinh(
    que_quan="Đà Nẵng",
    ten="Dung", 
    diem_tb=9.0,
    tuoi=17,
    lop="10A2"
)

print("👤 Profile học sinh:")
for key, value in hs1.items():
    print(f"  {key}: {value}")

print(f"\n👤 {hs2['ten']} - Lớp {hs2['lop']} - Điểm TB: {hs2['diem_tb']}")

TIP

Keyword arguments giúp code dễ đọc và không phụ thuộc vào thứ tự tham số

⭐ Tham số mặc định (Default Parameters)

python
def tinh_luong_nhan_vien(luong_co_ban, he_so=1.0, thuong=0, khoan_tru=0):
    """
    Tính lương nhân viên với các khoản phụ cấp
    - luong_co_ban: Lương cơ bản (bắt buộc)
    - he_so: Hệ số lương (mặc định 1.0)
    - thuong: Tiền thưởng (mặc định 0)
    - khoan_tru: Các khoản trừ (mặc định 0)
    """
    luong_thuc_linh = luong_co_ban * he_so + thuong - khoan_tru
    
    print(f"💰 TÍNH LƯƠNG NHÂN VIÊN")
    print(f"  Lương cơ bản: {luong_co_ban:,} VND")
    print(f"  Hệ số: {he_so}")
    print(f"  Thưởng: {thuong:,} VND")
    print(f"  Khấu trừ: {khoan_tru:,} VND")
    print(f"  → Thực lĩnh: {luong_thuc_linh:,} VND")
    
    return luong_thuc_linh

# Sử dụng với các tham số khác nhau
print("📋 Ví dụ 1: Chỉ lương cơ bản")
luong1 = tinh_luong_nhan_vien(5000000)

print("\n📋 Ví dụ 2: Có hệ số và thưởng")
luong2 = tinh_luong_nhan_vien(5000000, he_so=1.5, thuong=1000000)

print("\n📋 Ví dụ 3: Đầy đủ thông tin")
luong3 = tinh_luong_nhan_vien(
    luong_co_ban=6000000,
    he_so=2.0,
    thuong=2000000,
    khoan_tru=500000
)

def tao_email_cong_ty(ten, phong_ban="nhanvien", domain="company.com"):
    """Tạo email công ty theo chuẩn"""
    # Chuẩn hóa tên
    ten_clean = ten.lower().replace(" ", ".")
    email = f"{ten_clean}.{phong_ban}@{domain}"
    return email

# Test với tham số mặc định
print(f"\n📧 Email mặc định: {tao_email_cong_ty('Nguyen Van An')}")
print(f"📧 Email IT: {tao_email_cong_ty('Tran Thi Binh', 'it')}")
print(f"📧 Email custom: {tao_email_cong_ty('Le Van Chi', 'sales', 'newcompany.vn')}")

📦 *args và **kwargs

python
def tinh_tong_diem(*diem_so):
    """Tính tổng điểm của nhiều môn học (số lượng không cố định)"""
    if not diem_so:
        return 0
    
    tong = sum(diem_so)
    so_mon = len(diem_so)
    diem_tb = tong / so_mon
    
    print(f"📊 Điểm các môn: {diem_so}")
    print(f"📈 Tổng điểm: {tong}")
    print(f"📊 Điểm TB: {diem_tb:.2f}")
    
    return {"tong": tong, "trung_binh": diem_tb, "so_mon": so_mon}

# Test với số lượng tham số khác nhau
print("🎯 Học sinh 1 (3 môn):")
ket_qua1 = tinh_tong_diem(8, 7.5, 9)

print("\n🎯 Học sinh 2 (5 môn):")
ket_qua2 = tinh_tong_diem(8.5, 9, 7, 8, 9.5)

def tao_thong_tin_san_pham(ten_sp, gia, **chi_tiet):
    """
    Tạo thông tin sản phẩm với các chi tiết tùy chọn
    **chi_tiet có thể bao gồm: mau_sac, kich_thuoc, trong_luong, etc.
    """
    san_pham = {
        "ten": ten_sp,
        "gia": gia
    }
    
    # Thêm các chi tiết bổ sung
    san_pham.update(chi_tiet)
    
    print(f"🛍️ SẢN PHẨM: {ten_sp}")
    print(f"💰 Giá: {gia:,} VND")
    
    if chi_tiet:
        print("📋 Chi tiết:")
        for key, value in chi_tiet.items():
            print(f"  • {key.replace('_', ' ').title()}: {value}")
    
    return san_pham

# Test với **kwargs
sp1 = tao_thong_tin_san_pham("iPhone 15", 25000000)

print()
sp2 = tao_thong_tin_san_pham(
    "MacBook Air", 
    35000000,
    mau_sac="Xám",
    ram="8GB", 
    ssd="256GB",
    trong_luong="1.24kg"
)

def ham_linh_hoat(*args, **kwargs):
    """Hàm demo sử dụng cả *args và **kwargs"""
    print(f"🔢 Positional args: {args}")
    print(f"🏷️ Keyword args: {kwargs}")
    
    if args:
        print(f"📊 Tổng args: {sum(args) if all(isinstance(x, (int, float)) for x in args) else 'Không thể tính'}")

print("\n🧪 Test hàm linh hoạt:")
ham_linh_hoat(1, 2, 3, ten="An", tuoi=20, thanh_pho="Hà Nội")

WARNING

*args thu thập tham số vị trí, **kwargs thu thập tham số từ khóa. Sử dụng cẩn thận để tránh nhầm lẫn

📤 Giá trị trả về

📊 Return đơn giản

python
def kiem_tra_chan_le(so):
    """Kiểm tra số chẵn hay lẻ"""
    if so % 2 == 0:
        return "chẵn"
    else:
        return "lẻ"

def tinh_binh_phuong(x):
    """Tính bình phương của một số"""
    return x ** 2

def tao_cau_chao(ten, gio):
    """Tạo câu chào phù hợp với thời gian"""
    if 5 <= gio < 12:
        return f"Chào buổi sáng, {ten}!"
    elif 12 <= gio < 18:
        return f"Chào buổi chiều, {ten}!"
    else:
        return f"Chào buổi tối, {ten}!"

# Test các function
so_test = 7
print(f"🔢 Số {so_test} là số {kiem_tra_chan_le(so_test)}")
print(f"🔢 Bình phương của {so_test}{tinh_binh_phuong(so_test)}")
print(f"👋 {tao_cau_chao('An', 14)}")
print(f"👋 {tao_cau_chao('Bình', 20)}")

📋 Return nhiều giá trị

python
def phan_tich_chuoi(text):
    """Phân tích một chuỗi văn bản"""
    so_ky_tu = len(text)
    so_tu = len(text.split())
    so_cau = text.count('.') + text.count('!') + text.count('?')
    
    # Return nhiều giá trị dưới dạng tuple
    return so_ky_tu, so_tu, so_cau

def tinh_toan_co_ban(a, b):
    """Thực hiện các phép tính cơ bản với 2 số"""
    tong = a + b
    hieu = a - b
    tich = a * b
    thuong = a / b if b != 0 else "Không chia được cho 0"
    
    return tong, hieu, tich, thuong

def thong_ke_diem_thi(diem_list):
    """Thống kê điểm thi của lớp"""
    if not diem_list:
        return None, None, None, None
    
    diem_cao_nhat = max(diem_list)
    diem_thap_nhat = min(diem_list)
    diem_trung_binh = sum(diem_list) / len(diem_list)
    so_hoc_sinh = len(diem_list)
    
    return diem_cao_nhat, diem_thap_nhat, diem_trung_binh, so_hoc_sinh

# Test return nhiều giá trị
van_ban = "Python là ngôn ngữ tuyệt vời. Nó dễ học và mạnh mẽ!"
ky_tu, tu, cau = phan_tich_chuoi(van_ban)
print(f"📝 Văn bản có {ky_tu} ký tự, {tu} từ, {cau} câu")

# Unpacking với tên khác nhau
ketqua_cong, ketqua_tru, ketqua_nhan, ketqua_chia = tinh_toan_co_ban(20, 4)
print(f"🧮 20 + 4 = {ketqua_cong}")
print(f"🧮 20 - 4 = {ketqua_tru}")
print(f"🧮 20 × 4 = {ketqua_nhan}")
print(f"🧮 20 ÷ 4 = {ketqua_chia}")

# Thống kê điểm
diem_lop = [8.5, 7.0, 9.5, 6.5, 8.0, 9.0, 7.5, 8.5]
cao_nhat, thap_nhat, trung_binh, so_hs = thong_ke_diem_thi(diem_lop)
print(f"\n📊 THỐNG KÊ LỚP ({so_hs} học sinh):")
print(f"  🏆 Cao nhất: {cao_nhat}")
print(f"  📉 Thấp nhất: {thap_nhat}")
print(f"  📊 Trung bình: {trung_binh:.2f}")

🔄 Return có điều kiện

python
def phan_loai_hoc_sinh(diem_tb):
    """Phân loại học sinh theo điểm trung bình"""
    if diem_tb >= 9.0:
        return "Xuất sắc", "🏆"
    elif diem_tb >= 8.0:
        return "Giỏi", "🥇"
    elif diem_tb >= 6.5:
        return "Khá", "🥈"
    elif diem_tb >= 5.0:
        return "Trung bình", "📚"
    else:
        return "Yếu", "📉"

def tim_kiem_trong_danh_sach(danh_sach, gia_tri):
    """Tìm kiếm giá trị trong danh sách"""
    for i, item in enumerate(danh_sach):
        if item == gia_tri:
            return True, i  # Tìm thấy, trả về vị trí
    
    return False, -1  # Không tìm thấy

def kiem_tra_password(password):
    """Kiểm tra độ mạnh của password"""
    if len(password) < 6:
        return False, "Password phải có ít nhất 6 ký tự"
    
    co_chu_hoa = any(c.isupper() for c in password)
    co_chu_thuong = any(c.islower() for c in password)
    co_so = any(c.isdigit() for c in password)
    
    if not co_chu_hoa:
        return False, "Password phải có ít nhất 1 chữ hoa"
    if not co_chu_thuong:
        return False, "Password phải có ít nhất 1 chữ thường"
    if not co_so:
        return False, "Password phải có ít nhất 1 chữ số"
    
    return True, "Password đủ mạnh"

# Test return có điều kiện
cac_diem = [9.5, 7.8, 8.5, 5.2, 9.0]
for diem in cac_diem:
    xep_loai, icon = phan_loai_hoc_sinh(diem)
    print(f"{icon} Điểm {diem}: {xep_loai}")

# Test tìm kiếm
danh_sach_ten = ["An", "Bình", "Chi", "Dung"]
tim_thay, vi_tri = tim_kiem_trong_danh_sach(danh_sach_ten, "Chi")
if tim_thay:
    print(f"\n🔍 Tìm thấy 'Chi' ở vị trí {vi_tri}")
else:
    print("\n❌ Không tìm thấy")

# Test password
test_passwords = ["123", "abcDEF", "Abc123", "password", "MyPass123"]
print(f"\n🔐 KIỂM TRA PASSWORD:")
for pwd in test_passwords:
    hop_le, thong_bao = kiem_tra_password(pwd)
    status = "✅" if hop_le else "❌"
    print(f"  {status} '{pwd}': {thong_bao}")

❌ Function không return (return None)

python
def in_thong_tin_hoc_sinh(ten, lop, diem):
    """In thông tin học sinh (không return gì)"""
    print(f"👤 Học sinh: {ten}")
    print(f"🏫 Lớp: {lop}")
    print(f"📊 Điểm TB: {diem}")
    print("-" * 30)

def cap_nhat_diem(hoc_sinh_dict, ten, diem_moi):
    """Cập nhật điểm cho học sinh (modify in-place)"""
    if ten in hoc_sinh_dict:
        diem_cu = hoc_sinh_dict[ten]
        hoc_sinh_dict[ten] = diem_moi
        print(f"✅ Đã cập nhật điểm {ten}: {diem_cu}{diem_moi}")
    else:
        print(f"❌ Không tìm thấy học sinh {ten}")

def gui_thong_bao(tin_nhan):
    """Gửi thông báo (mô phỏng)"""
    print(f"📢 THÔNG BÁO: {tin_nhan}")
    print("✅ Đã gửi thành công!")

# Test function không return
in_thong_tin_hoc_sinh("Nguyễn Văn An", "10A1", 8.5)

# Function không return sẽ trả về None
ket_qua = in_thong_tin_hoc_sinh("Trần Thị Bình", "10A2", 9.0)
print(f"Kết quả return: {ket_qua}")  # None

# Modify dữ liệu in-place
bang_diem = {"An": 8.0, "Bình": 7.5, "Chi": 9.0}
print(f"\nBảng điểm ban đầu: {bang_diem}")

cap_nhat_diem(bang_diem, "An", 8.5)
cap_nhat_diem(bang_diem, "Dung", 7.0)  # Không tồn tại

print(f"Bảng điểm sau cập nhật: {bang_diem}")

gui_thong_bao("Ngày mai nghỉ học do mưa bão")

📝 Bài tập thực hành

Bài tập 1: Calculator nâng cao

Viết function calculator nhận operation (+, -, *, /) và số lượng tham số không cố định:

python
# Đáp án
def calculator(operation, *numbers):
    if not numbers:
        return "Cần ít nhất 1 số"
    
    if operation == "+":
        return sum(numbers)
    elif operation == "-":
        result = numbers[0]
        for num in numbers[1:]:
            result -= num
        return result
    elif operation == "*":
        result = 1
        for num in numbers:
            result *= num
        return result
    elif operation == "/":
        result = numbers[0]
        for num in numbers[1:]:
            if num == 0:
                return "Không chia được cho 0"
            result /= num
        return result
    else:
        return "Phép toán không hợp lệ"

# Test
print(calculator("+", 1, 2, 3, 4))  # 10
print(calculator("*", 2, 3, 4))     # 24

📚 Tóm tắt

Tham số:

  • Positional: Theo thứ tự, bắt buộc
  • Keyword: Theo tên, không phụ thuộc thứ tự
  • Default: Có giá trị mặc định, tùy chọn
  • *args: Thu thập tham số vị trí dư thừa
  • **kwargs: Thu thập tham số từ khóa dư thừa

Return:

  • Single: Trả về 1 giá trị
  • Multiple: Trả về tuple, có thể unpacking
  • Conditional: Return khác nhau tùy điều kiện
  • None: Function không return hoặc chỉ thực hiện action

Best practices:

  • 📝 Luôn viết docstring mô tả tham số và return
  • 🎯 Tham số bắt buộc trước, tùy chọn sau
  • 🔄 Sử dụng return để function có thể compose được
  • ⚠️ Kiểm tra tham số hợp lệ trước khi xử lý

Lời khuyên

Function với tham số và return rõ ràng sẽ dễ test, debug và tái sử dụng hơn

🐍 Khóa học Python căn bản bằng tiếng Việt