Giới thiệu
Bạn đã bao giờ gặp tình huống cần truyền nhiều đối số không cố định vào hàm Python chưa? Chẳng hạn như khi viết một hàm tính tổng mà không biết trước sẽ có bao nhiêu số cần tính, hay tạo một hàm xử lý dữ liệu với các tham số thay đổi linh hoạt? Đây chính là lúc bạn cần đến khái niệm “đối số tùy ý” (arbitrary arguments) trong Python.
Sử dụng đối số tùy ý là giải pháp linh hoạt giúp bạn xử lý đa dạng input mà không cần định nghĩa cứng nhắc từng tham số. Python cung cấp hai cách thức chính để làm điều này: *args
và **kwargs
– hai công cụ mạnh mẽ mà mọi lập trình viên Python nên nắm vững.

Bài viết này sẽ giải thích chi tiết khái niệm *args
và **kwargs
, cách dùng chúng một cách hiệu quả, và so sánh hai kiểu đối số này. Chúng ta cùng khám phá những ví dụ thực tế, các lưu ý quan trọng khi sử dụng, cũng như những mẹo hữu ích để nâng cao kỹ năng lập trình Python của bạn.
Khái niệm về đối số tùy ý trong Python
*args
là gì và khi nào nên dùng?
*args
là cách viết tắt của “arguments” và cho phép bạn truyền nhiều đối số không xác định dưới dạng tuple vào hàm. Dấu sao (*
) trước args
báo hiệu cho Python biết rằng hàm này có thể nhận bất kỳ số lượng đối số nào.
Bạn nên sử dụng *args
khi không biết trước số lượng đối số cần xử lý. Ví dụ điển hình là khi viết hàm tính toán với số lượng input thay đổi, hoặc khi muốn tạo wrapper function cho các hàm khác.

Ví dụ đơn giản minh họa cú pháp hàm dùng *args
:
def tinh_tong(*args):
return sum(args)
# Gọi hàm với số lượng tham số khác nhau
print(tinh_tong(1, 2, 3)) # Kết quả: 6
print(tinh_tong(5, 10, 15, 20)) # Kết quả: 50
**kwargs
là gì và khi nào nên dùng?
**kwargs
là cách viết tắt của “keyword arguments” và cho phép truyền các đối số từ khóa không cố định dưới dạng dictionary vào hàm. Hai dấu sao (**
) trước kwargs
cho Python biết rằng những tham số này sẽ được lưu dưới dạng từ điển.
**kwargs
thích hợp khi bạn muốn đặt tên rõ ràng cho từng tham số đầu vào, giúp code dễ đọc và dễ bảo trì hơn. Điều này đặc biệt hữu ích khi làm việc với API, cấu hình hệ thống, hoặc các hàm có nhiều tùy chọn.

Ví dụ minh họa cú pháp và cách truy cập giá trị trong **kwargs
:
def thong_tin_nguoi_dung(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
# Gọi hàm với các đối số từ khóa
thong_tin_nguoi_dung(ten="Duc", tuoi=25, nghe_nghiep="Developer")
Cách sử dụng *args và **kwargs trong Python
Cú pháp và ví dụ thực tế với *args
Cách khai báo hàm có *args
khá đơn giản. Bạn chỉ cần thêm *args
vào danh sách tham số của hàm. Lưu ý rằng tên args
không bắt buộc – bạn có thể dùng bất kỳ tên nào sau dấu sao, nhưng args
là quy ước phổ biến.

Ví dụ hàm tính tổng của nhiều số:
def tinh_tong_nang_cao(*so_lieu, he_so=1):
tong = sum(so_lieu) * he_so
print(f"Các số: {so_lieu}")
print(f"Tổng với hệ số {he_so}: {tong}")
return tong
# Điều chỉnh và gọi hàm với số lượng tham số khác nhau
tinh_tong_nang_cao(1, 2, 3, 4, he_so=2)
tinh_tong_nang_cao(10, 20, he_so=0.5)
Bạn cũng có thể kết hợp *args
với các tham số thông thường, nhưng *args
phải đứng sau các tham số vị trí thông thường và trước các tham số từ khóa.
Cú pháp và ví dụ minh họa với **kwargs
Khai báo hàm nhận **kwargs
cũng tương tự như *args
. Bạn thêm **kwargs
vào cuối danh sách tham số. Trong hàm, kwargs
sẽ trở thành một dictionary chứa tất cả các đối số từ khóa được truyền vào.

Ví dụ hàm in ra tên và giá trị của các đối số từ khóa:
def cau_hinh_he_thong(phien_ban="1.0", **kwargs):
print(f"Phiên bản hệ thống: {phien_ban}")
print("Cấu hình bổ sung:")
for ten_cau_hinh, gia_tri in kwargs.items():
print(f" {ten_cau_hinh}: {gia_tri}")
# Kết hợp truy cập và xử lý trong hàm
cau_hinh_he_thong(
phien_ban="2.1",
database_host="localhost",
debug_mode=True,
max_connections=100
)
So sánh *args
và **kwargs
Điểm giống nhau
Cả *args
và **kwargs
đều được sử dụng để truyền đối số không cố định vào hàm Python. Chúng giúp hàm của bạn trở nên linh hoạt hơn và có tính tái sử dụng cao, thay vì phải định nghĩa cứng nhắc từng tham số.
Cả hai đều sử dụng cú pháp với dấu sao (*
) để báo hiệu cho Python biết rằng hàm có thể nhận nhiều tham số. Điều này giúp code của bạn gọn gàng và dễ mở rộng khi cần thiết.

Cả *args
và **kwargs
đều có thể được kết hợp trong cùng một hàm, giúp tạo ra những hàm cực kỳ linh hoạt có thể xử lý mọi loại input.
Điểm khác biệt
Sự khác biệt chính giữa *args
và **kwargs
nằm ở cách thức truyền và lưu trữ dữ liệu. *args
truyền đối số theo vị trí và lưu trữ dưới dạng tuple, trong khi **kwargs
truyền đối số theo cặp key-value và lưu trữ dưới dạng dictionary.
*args
phù hợp khi bạn có nhiều giá trị cùng loại và không cần đặt tên riêng biệt. **kwargs
lại phù hợp khi muốn đặt tên rõ ràng cho từng tham số, giúp code dễ hiểu và maintain.
Về mặt ứng dụng thực tế, *args
thường dùng cho các phép tính toán với nhiều số, còn **kwargs
phổ biến trong việc cấu hình, tùy chọn, và truyền tham số cho API.
Tình huống thực tế và bài tập áp dụng
Ví dụ thực tế trong dự án Python
Trong thực tế, bạn sẽ thường gặp tình huống cần xử lý dữ liệu có input thay đổi về số lượng hoặc kiểu tham số. Hãy xem một ví dụ về hàm xử lý lọc dữ liệu sử dụng cả *args
và **kwargs
:

def loc_du_lieu(danh_sach, *dieu_kien_loc, **tuy_chon):
"""
Hàm lọc dữ liệu linh hoạt
- danh_sach: dữ liệu cần lọc
- *dieu_kien_loc: các điều kiện lọc theo vị trí
- **tuy_chon: các tùy chọn như sort, limit, reverse
"""
ket_qua = danh_sach.copy()
# Áp dụng các điều kiện lọc
for dieu_kien in dieu_kien_loc:
ket_qua = [item for item in ket_qua if dieu_kien(item)]
# Xử lý các tùy chọn
if tuy_chon.get('sap_xep'):
ket_qua.sort(key=tuy_chon.get('key'))
if tuy_chon.get('dao_nguoc'):
ket_qua.reverse()
if tuy_chon.get('gioi_han'):
ket_qua = ket_qua[:tuy_chon.get('gioi_han')]
return ket_qua
# Ví dụ sử dụng
so_lieu = [1, 5, 10, 15, 20, 25, 30]
ket_qua = loc_du_lieu(
so_lieu,
lambda x: x > 10, # *args: điều kiện 1
lambda x: x < 25, # *args: điều kiện 2
sap_xep=True, # **kwargs
dao_nguoc=True, # **kwargs
gioi_han=2 # **kwargs
)
print(ket_qua) # [20, 15]
Bài tập tự luyện giúp củng cố kiến thức
Để củng cố kiến thức, hãy thử làm những bài tập sau:

Bài 1: Tạo hàm tính điểm trung bình với *args
:
def tinh_diem_trung_binh(*diem_so):
# Code của bạn ở đây
pass
Bài 2: Viết hàm in thông tin người dùng với **kwargs
:
def in_thong_tin(**thong_tin):
# Code của bạn ở đây
pass
Bài 3: Bài tập kết hợp cả hai - tạo hàm báo cáo kết quả học tập:
def bao_cao_hoc_tap(ten_hoc_sinh, *mon_hoc_diem, **thong_tin_bo_sung):
"""
Tạo báo cáo kết quả học tập
- ten_hoc_sinh: tên học sinh
- *mon_hoc_diem: các điểm môn học
- **thong_tin_bo_sung: thông tin như lớp, niên khóa, ghi chú
"""
# Thử viết code để xử lý và in báo cáo
pass
Các lỗi phổ biến và cách khắc phục
Lỗi truyền đối số sai kiểu hoặc thiếu tham số
Khi làm việc với *args
và **kwargs
, bạn có thể gặp lỗi TypeError
khá thường xuyên. Lỗi này usually xảy ra khi truyển sai kiểu dữ liệu hoặc thiếu tham số bắt buộc.

Để debug và sửa lỗi nhanh, hãy luôn kiểm tra:
- Thứ tự tham số trong định nghĩa hàm
- Kiểu dữ liệu của các đối số được truyền vào
- Có đủ tham số bắt buộc hay không
Ví dụ về cách xử lý lỗi:
def ham_an_toan(*args, **kwargs):
try:
# Kiểm tra args có rỗng không
if not args:
raise ValueError("Cần ít nhất một đối số")
# Kiểm tra kiểu dữ liệu
for arg in args:
if not isinstance(arg, (int, float)):
raise TypeError(f"Đối số {arg} phải là số")
return sum(args)
except (ValueError, TypeError) as e:
print(f"Lỗi: {e}")
return None
Lỗi trùng tên đối số khi dùng *args
và **kwargs
cùng hàm
Một lỗi khác thường gặp là trùng tên đối số khi kết hợp *args
và **kwargs
trong cùng một hàm. Python có thứ tự tham số cố định: tham số thông thường → *args
→ tham số từ khóa → **kwargs
.
Lời khuyên để tránh nhầm lẫn thường gặp:
- Luôn theo đúng thứ tự:
def ham(param, *args, keyword_param=default, **kwargs)
- Không đặt tên trùng giữa tham số thông thường và key trong
**kwargs
- Sử dụng tên biến có ý nghĩa, tránh viết tắt khó hiểu
Mẹo và best practices khi dùng đối số tùy ý
Khi sử dụng đối số tùy ý trong Python, hãy ghi nhớ những mẹo quan trong sau. Luôn khai báo *args
trước **kwargs
trong định nghĩa hàm - đây là quy tắc cú pháp bắt buộc của Python.
Dùng tên biến dễ hiểu và tránh lạm dụng gây khó đọc code. Thay vì viết def func(*args, **kwargs)
cho mọi hàm, hãy cân nhắc xem có thực sự cần thiết không. Đôi khi việc định nghĩa rõ ràng các tham số sẽ giúp code dễ hiểu hơn.

Kết hợp kiểm tra và validate dữ liệu input trong hàm. Việc này giúp phát hiện lỗi sớm và đảm bảo hàm hoạt động đúng như mong đợi:
def ham_an_toan(*so_nguyen, **tuy_chon):
# Validate *args
if not all(isinstance(x, int) for x in so_nguyen):
raise TypeError("Tất cả đối số phải là số nguyên")
# Validate **kwargs
allowed_options = ['he_so', 'lam_tron']
for key in tuy_chon:
if key not in allowed_options:
raise ValueError(f"Tùy chọn '{key}' không được hỗ trợ")
Lập tài liệu và chú thích rõ ràng khi dùng đối số tùy ý. Điều này đặc biệt quan trọng vì người khác (kể cả bạn trong tương lai) có thể không hiểu ngay được hàm nhận những tham số gì.
Cuối cùng, hãy tận dụng tốt *args
và **kwargs
để tăng tính mở rộng và linh hoạt cho codebase của bạn, nhưng đừng quên cân bằng giữa sự linh hoạt và tính rõ ràng của code.
Kết luận
*args
và **kwargs
thực sự là những công cụ mạnh mẽ giúp bạn xử lý đa dạng đầu vào hàm Python một cách hiệu quả. Thông qua bài viết này, chúng ta đã cùng tìm hiểu chi tiết về cú pháp, cách sử dụng, và những khác biệt quan trọng giữa hai loại đối số tùy ý này.

Việc hiểu rõ cách thức hoạt động, biết cách áp dụng phù hợp, và nắm được những best practices sẽ giúp bạn viết code Python gọn gàng, linh hoạt và hiệu quả hơn rất nhiều. Đặc biệt khi làm việc với các dự án lớn, khả năng xử lý input động này sẽ trở thành lợi thế lớn.
Hãy dành thời gian thực hành qua các ví dụ và bài tập mà chúng tôi đã đề xuất để nắm chắc kiến thức. Bắt đầu từ những ví dụ đơn giản, sau đó dần áp dụng vào các tình huống phức tạp hơn trong dự án thực tế của bạn.
Cuối cùng, đừng quên tham khảo tài liệu chính thức của Python để tiếp tục đi sâu và cập nhật kiến thức liên tục. Lập trình là một hành trình học hỏi không ngừng, và việc nắm vững những khái niệm cơ bản như *args
và **kwargs
sẽ là nền tảng vững chắc cho con đường phát triển kỹ năng Python của bạn.
Hàm trong Python: Định nghĩa, Cách khai báo, Sử dụng và Mẹo Tối ưu
Tìm hiểu các kiểu dữ liệu trong Python và cách sử dụng hiệu quả
Tìm hiểu List trong Python: Định nghĩa, khai báo, thao tác cơ bản và mẹo xử lý hiệu quả
Tìm hiểu Vòng lặp for trong Python: Cú pháp, Cách dùng, Ví dụ và Mẹo tối ưu
Tìm hiểu lệnh if trong Python: Khái niệm, cú pháp và cách sử dụng hiệu quả
Tìm hiểu vòng lặp while trong Python: Cú pháp, ví dụ và mẹo tối ưu hóa code
Toàn bộ kiến thức về toán tử trong Python: Hướng dẫn đầy đủ và ví dụ dễ hiểu
Tìm hiểu về Set trong Python: Khái niệm, cách tạo, thao tác cơ bản và ứng dụng thực tiễn
Tìm hiểu Tuple trong Python: Định nghĩa, Cách Tạo, Đặc Tính Bất Biến và Ứng Dụng Thực Tế
Chia sẻ Tài liệu học Python