Arbitrary arguments là một cơ chế giúp bạn định nghĩa các hàm chấp nhgaanj một số lượng đối số đầu vào không xác định trước. Trong bài viết này mình sẽ giúp bạn tìm hiểu rõ hơn về rbitrary arguments và cách cơ chế này hoạt động bên trong Python.
Arbitrary Arguments (*args) trong Python là gì?
Arbitrary Arguments (*args
) trong Python là một cơ chế mạnh mẽ cho phép bạn định nghĩa các hàm có khả năng nhận vào một số lượng tùy ý các tham số vị trí (positional arguments). Thay vì phải cố định số lượng tham số mà hàm có thể chấp nhận, bạn có thể tạo ra một hàm linh hoạt, tự động thích ứng với bất kỳ số lượng đầu vào nào bạn truyền vào.
Cụ thể, để khai báo một tham số như vậy trong định nghĩa hàm, bạn sẽ sử dụng tiền tố dấu hoa thị đơn *
đặt trước tên tham số. Thông thường, người ta hay dùng *args
(nhưng bạn cũng có thể dùng tên khác)
- Đối với các đối số vị trí tùy ý, chúng ta sẽ thêm dấu
*
vào trước tên tham số trong định nghĩa hàm (ví dụ:*args
). - Đối với các đối số từ khóa tùy ý, chúng ta sẽ thêm dấu
**
vào trước tên tham số (ví dụ:**kwargs
).
Ví dụ về arbitrary arguments trong Python
Dưới đây là một ví dụ minh họa cách sử dụng đối số vị trí tùy ý, hay đối số có độ dài biến đổi:
# Hàm tính tích các số
def tinh_tich(*cac_so):
tich = 1
for so in cac_so:
tich *= so
return tich
ket_qua = tinh_tich(2, 3, 4, 5)
print (ket_qua)
ket_qua = tinh_tich(7, 8)
print(ket_qua)
Biến cac_so
, có tiền tố là *
, sẽ lưu trữ tất cả các giá trị được truyền vào hàm khi được gọi. Bên trong hàm, cac_so
hoạt động như một tuple
, tức là một chuỗi các phần tử không thay đổi, và chúng ta có thể duyệt qua từng phần tử bằng vòng lặp for
.
Đoạn code trên sẽ có kết quả như sau:
120
56
Giải thích code:
def tinh_tich(*cac_so):
: Dòng này định nghĩa hàmtinh_tich
chấp nhận một số lượng đối số vị trí tùy ý. Các đối số này sẽ được gom thành một tuple và lưu vào biếncac_so
.tich = 1
: Khởi tạo biếntich
(tích số) bằng 1.for so in cac_so:
: Vòng lặp này duyệt qua từng phần tử (từng số) trong tuplecac_so
.tich *= so
: Với mỗi số, ta nhân số đó vào biếntich
.return tich
: Hàm trả về kết quả tính tích cuối cùng.ket_qua = tinh_tich(2, 3, 4, 5)
vàprint(ket_qua)
: Dòng lệnh này gọi hàmtinh_tich
với các giá trị 2, 3, 4, và 5, sau đó in ra kết quả.ket_qua = tinh_tich(7, 8)
vàprint(ket_qua)
: Tương tự, gọi hàm với các số 7, 8 và in kết quả.
Kết hợp required arguments với arbitrary arguments
Trong Python, hoàn toàn có thể định nghĩa một hàm có một số tham số bắt buộc đi kèm với một chuỗi các tham số tùy ý có độ dài biến đổi.
Ví dụ
Ví dụ sau có hàm tinh_diem_trung_binh_tot()
để tính điểm trung bình của một bài kiểm tra bắt buộc và điểm cao nhất của các bài kiểm tra tùy chọn:
# Tính điểm trung bình của bài bắt buộc và điểm cao nhất trong các bài sau
def tinh_diem_trung_binh_tot(diem_bat_buoc, *cac_diem_con_lai):
diem_cao_nhat = max(cac_diem_con_lai)
return (diem_bat_buoc + diem_cao_nhat) / 2
ket_qua = tinh_diem_trung_binh_tot(60, 70, 80, 55)
print (ket_qua)
ket_qua = tinh_diem_trung_binh_tot(70, 85, 90)
print(ket_qua)
Khi gọi hàm tinh_diem_trung_binh_tot()
, giá trị đầu tiên được truyền vào sẽ được gán cho tham số bắt buộc diem_bat_buoc
, và các giá trị còn lại sẽ được gom vào một tuple tên cac_diem_con_lai
. Sau đó, hàm sẽ tìm điểm cao nhất trong tuple này và sử dụng nó để tính điểm trung bình với diem_bat_buoc
.
Đoạn code trên sẽ cho ra kết quả như sau:
70.0
80.0
Giải thích Code:
def tinh_diem_trung_binh_tot(diem_bat_buoc, *cac_diem_con_lai):
: Hàmtinh_diem_trung_binh_tot
được định nghĩa với một tham số bắt buộc làdiem_bat_buoc
và một số lượng tùy ý các tham số vị trí (các điểm còn lại) gom thành tuplecac_diem_con_lai
.diem_cao_nhat = max(cac_diem_con_lai)
: Tìm điểm số lớn nhất trong tuple các điểm còn lại và gán chodiem_cao_nhat
.return (diem_bat_buoc + diem_cao_nhat) / 2
: Tính điểm trung bình của điểm bắt buộc và điểm cao nhất, rồi trả về kết quả.ket_qua = tinh_diem_trung_binh_tot(60, 70, 80, 55)
vàprint (ket_qua)
: Lệnh này gọi hàm và truyền giá trị tham số, kết quả in ra là 70.0ket_qua = tinh_diem_trung_binh_tot(70, 85, 90)
vàprint (ket_qua)
: Tương tự gọi hàm, truyền các giá trị tham số khác và in ra kết quả 80.0
Arbitrary Keyword Arguments (**kwargs) trong Python
Khi một biến trong danh sách tham số của hàm có tiền tố là hai dấu hoa thị (**
), hàm đó có khả năng tiếp nhận một số lượng tham số từ khóa tùy ý. Biến này sẽ trở thành một dictionary (từ điển) chứa các cặp key-value, trong đó khóa là tên của tham số từ khóa và giá trị là giá trị tương ứng được truyền vào.
Ví dụ
Để hình dung rõ hơn về cách tham số từ khóa tùy ý hoạt động, hãy cùng xem ví dụ dưới đây:
def in_thong_tin_ca_nhan(**thong_tin):
for key, value in thong_tin.items():
print(f"{key}: {value}")
print("Thông tin cá nhân 1:")
in_thong_tin_ca_nhan(ten="Lan", tuoi=25)
print("\nThông tin cá nhân 2:")
in_thong_tin_ca_nhan(ten="Nam", tuoi=30, email="nam@example.com", nghe_nghiep="kỹ sư")
Hàm in_thong_tin_ca_nhan()
có tham số **thong_tin
. Khi gọi hàm, bạn có thể truyền vào bất kỳ số lượng tham số từ khóa nào bạn muốn. Bên trong hàm, thong_tin
sẽ là một dictionary. Chúng ta sử dụng phương thức items()
để duyệt qua các cặp key-value trong dictionary và in ra.
Khi thực thi đoạn code trên, bạn sẽ nhận được kết quả như sau:
Thông tin cá nhân 1:
ten: Lan
tuoi: 25
Thông tin cá nhân 2:
ten: Nam
tuoi: 30
email: nam@example.com
nghe_nghiep: kỹ sư
Giải thích code:
def in_thong_tin_ca_nhan(**thong_tin):
: Định nghĩa một hàm tênin_thong_tin_ca_nhan
có tham số**thong_tin
cho phép nhận các tham số từ khóa tùy ý. Các tham số này sẽ được gom lại thành một dictionary và gán cho biếnthong_tin
.for key, value in thong_tin.items():
: Duyệt qua các cặp khóa-giá trị trong dictionarythong_tin
sử dụng vòng lặpfor
.print(f"{key}: {value}")
: In ra màn hình khóa (key
) và giá trị (value
) tương ứng.- Các dòng lệnh gọi hàm
in_thong_tin_ca_nhan()
: với các tham số từ khóa khác nhau để minh họa cách sử dụng**kwargs
.
Kết hợp Multiple Arguments với Arbitrary Keyword Arguments
Khi một hàm sử dụng kết hợp nhiều loại tham số, các tham số từ khóa tùy ý (với tiền tố **
) nên được đặt sau cùng trong danh sách tham số, sau cả các tham số vị trí, tham số từ khóa thông thường và các tham số vị trí tùy ý (với tiền tố *
).
Ví dụ
Hãy tưởng tượng tình huống một học sinh phải học các môn bắt buộc là Toán và Khoa học, ngoài ra học sinh có thể chọn học thêm một số môn tự chọn khác.
Đoạn code dưới đây định nghĩa hàm tinh_diem_trung_binh()
, trong đó điểm môn Toán và môn Khoa học được lưu trong các tham số bắt buộc, còn điểm các môn tự chọn (số lượng môn không cố định) được lưu trong tham số tùy ý với dạng từ khóa:
def tinh_diem_trung_binh(toan, khoa_hoc, **cac_mon_tu_chon):
print ("Toán:", toan)
print ("Khoa học:", khoa_hoc)
tong_diem = toan + khoa_hoc
for ten_mon, diem_mon in cac_mon_tu_chon.items():
print ("{}:{}".format(ten_mon, diem_mon))
tong_diem += diem_mon
return tong_diem / (len(cac_mon_tu_chon) + 2)
ket_qua = tinh_diem_trung_binh(toan=85, khoa_hoc=90, Van=78, Anh=82, Su=88, Dia = 80)
print ("Điểm trung bình:", ket_qua)
Đoạn code trên sẽ in ra kết quả:
Toán: 85
Khoa học: 90
Van:78
Anh:82
Su:88
Dia:80
Điểm trung bình: 83.83333333333333
Giải thích code:
def tinh_diem_trung_binh(toan, khoa_hoc, **cac_mon_tu_chon):
: Định nghĩa hàm với tham sốtoan
,khoa_hoc
là các tham số vị trí bắt buộc và tham số**cac_mon_tu_chon
là tham số từ khóa tùy ý, nơi ta sẽ truyền vào các môn tự chọn.print ("Toán:", toan)
vàprint ("Khoa học:", khoa_hoc)
: In ra điểm Toán và Khoa học.tong_diem = toan + khoa_hoc
: Khởi tạo biếntong_diem
để lưu tổng điểm ban đầu của các môn bắt buộc.for ten_mon, diem_mon in cac_mon_tu_chon.items():
: Duyệt qua các cặp tên môn (khóa) và điểm môn (giá trị) trong từ điểncac_mon_tu_chon
.print ("{}:{}".format(ten_mon, diem_mon))
: In ra điểm của các môn tự chọn.tong_diem += diem_mon
: Cộng dồn điểm các môn tự chọn vào tổng điểm.return tong_diem / (len(cac_mon_tu_chon) + 2)
: Tính và trả về điểm trung bình cộng (tổng điểm chia cho số môn).ket_qua = tinh_diem_trung_binh(toan=85, khoa_hoc=90, Van=78, Anh=82, Su=88, Dia = 80)
: Gọi hàm với điểm các môn bắt buộc và một vài môn tự chọn.print ("Điểm trung bình:", ket_qua)
: In kết quả tính điểm trung bình.
Lời kết
Chúng ta vừa cùng nhau tìm hiểu chi tiết về Arbitrary Arguments trong Python, một tính năng mạnh mẽ giúp hàm trở nên linh hoạt hơn trong việc xử lý số lượng đối số không xác định. Hy vọng kiến thức này sẽ giúp bạn ứng dụng thành công vào các dự án của mình, tạo ra những đoạn code Python tối ưu và hiệu quả. Chúc bạn có những trải nghiệm thú vị khi khám phá thêm về Python!