Khai Báo Hàm Trong Python Hiệu Quả

Hàm trong Python

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.

Hàm trong Python
Hình 1. Hàm trong Python

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.

Khai báo hàm trong Python
Hình 2. Khai báo hàm trong Python

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.

Gọi hàm trong Python
Hình 3. Gọi hàm trong Python

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.

Rate this post

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *