Positional Only Arguments là một tính năng ít được biết đến nhưng vô cùng hữu ích trong Python. Chúng cho phép các nhà phát triển định nghĩa tham số của hàm chỉ được truyền theo vị trí, thay vì sử dụng keyword. Trong bài viết này, mình sẽ hướng dẫn bạn cách sử dụng và khai thác tối đa tính năng này, giúp nâng cao kỹ năng lập trình Python của bạn.
Positional Only Arguments trong Python là gì?
Positional Only Arguments trong Python là cách định nghĩa các tham số của hàm sao cho chúng chỉ có thể nhận giá trị dựa trên vị trí xuất hiện của chúng khi gọi hàm, chứ không phải thông qua tên tham số (tức là sử dụng “keyword arguments”). Điều này có nghĩa là bạn không thể gán giá trị cho các tham số này bằng cách dùng cú pháp ten_tham_so=gia_tri
khi gọi hàm, mà bắt buộc phải truyền giá trị trực tiếp dựa trên thứ tự của chúng.
Để khai báo một hoặc nhiều tham số của hàm là “positional-only”, bạn sử dụng ký tự gạch chéo (/
) trong danh sách các tham số của hàm. Mọi tham số nằm bên trái ký tự gạch chéo này đều sẽ được coi là tham số “positional-only”.
Ví dụ điển hình về việc sử dụng đối số chỉ nhận giá trị theo vị trí trong Python là hàm input()
. Cú pháp của hàm input(
) như sau:
input(prompt = "")
prompt
ở đây là một chuỗi ký tự dùng để giải thích và hướng dẫn người dùng nhập liệu. Tuy nhiên, điều quan trọng cần nhớ là bạn không thể truyền giá trị cho tham số prompt bằng cách sử dụng từ khóa (ví dụ prompt=”Nội dung gợi ý”). prompt chỉ có thể nhận giá trị thông qua vị trí của đối số trong hàm.
Ví dụ: Lỗi khi sử dụng keyword arguments với tham số positional-only
Xem qua ví dụ sau, ta sẽ thử truyền giá trị cho tham số prompt của hàm input()
bằng keyword argument, và xem điều gì sẽ xảy ra:
ten = input(prompt="Nhập tên của bạn: ")
Khi thực thi đoạn code trên, bạn sẽ nhận được thông báo lỗi như sau:
TypeError: input() takes no keyword arguments
Thông báo lỗi này chỉ ra rằng hàm input() không chấp nhận các đối số từ khóa (keyword arguments). Điều đó có nghĩa là chúng ta bắt buộc phải cung cấp giá trị cho đối số prompt (hoặc không cung cấp) thông qua vị trí của nó.
Trong trường hợp của hàm input()
, bạn chỉ có thể truyền một chuỗi hướng dẫn người dùng nhập liệu như thế này:
ten = input("Nhập tên của bạn: ") # Đúng
Hoặc:
ten = input() # Cũng đúng (sẽ không hiển thị chuỗi hướng dẫn)
Trong đó, bạn không chỉ định tên đối số prompt, và Python sẽ tự hiểu đây là đối số đầu tiên, và do đó cũng là tham số positional-only.
Các ví dụ về positional-only arguments trong Python
Để hiểu rõ hơn về cách sử dụng đối số chỉ nhận giá trị theo vị trí (positional-only arguments), hãy cùng xem xét một số ví dụ cụ thể:
Ví dụ 1
Trong ví dụ này, chúng ta sẽ tạo một hàm tinh_lai_suat()
và khai báo cả hai đối số so_tien
và lai_suat
là các đối số chỉ nhận giá trị theo vị trí bằng cách đặt dấu gạch chéo /
ở cuối danh sách các đối số:
def tinh_lai_suat(so_tien, lai_suat, /):
tien_lai = so_tien * lai_suat / 100
return tien_lai
print(tinh_lai_suat(300000, 5))
Khi bạn thực thi đoạn code này, kết quả sẽ được hiển thị như sau:
15000.0
Giải thích code:
def tinh_lai_suat(so_tien, lai_suat, /):
: Câu lệnh này định nghĩa hàmtinh_lai_suat()
với hai đối sốso_tien
(số tiền) vàlai_suat
(lãi suất). Dấu gạch chéo/
ở cuối danh sách đối số chỉ ra rằng cảso_tien
vàlai_suat
đều là positional-only arguments.tien_lai = so_tien * lai_suat / 100
: Đây là công thức tính tiền lãi. Hàm sẽ tính toán và gán kết quả vào biếntien_lai
.return tien_lai
: Hàm sẽ trả về giá trị của biếntien_lai
.print(tinh_lai_suat(300000, 5))
: Câu lệnh này gọi hàmtinh_lai_suat()
với các giá trị300000
choso_tien
và5
cholai_suat
, sau đó in kết quả trả về của hàm (tức là tiền lãi) ra màn hình.
Ví dụ 2
Như đã đề cập, việc truyền giá trị cho các đối số chỉ nhận vị trí (positional-only arguments) bằng từ khóa (keyword arguments) sẽ dẫn đến lỗi. Chúng ta hãy xem xét một ví dụ cụ thể:
def tinh_lai_suat(so_tien, lai_suat, /):
tien_lai = so_tien * lai_suat / 100
return tien_lai
print(tinh_lai_suat(so_tien=250000, lai_suat=6))
Khi chạy đoạn code trên, bạn sẽ nhận được thông báo lỗi sau:
TypeError: tinh_lai_suat() got some positional-only arguments passed as keyword arguments: ‘so_tien, lai_suat’
Giải thích lỗi:
- Trong ví dụ này, hàm
tinh_lai_suat
vẫn được định nghĩa giống như ví dụ trước, với hai đối sốso_tien
vàlai_suat
được đánh dấu là positional-only bằng dấu gạch chéo/
. - Tuy nhiên, ở dòng
print(tinh_lai_suat(so_tien=250000, lai_suat=6))
, chúng ta cố tình truyền giá trị cho các đối số này bằng cách sử dụng từ khóa (keyword arguments)so_tien=
vàlai_suat=
. - Python đã phát hiện ra điều này và hiển thị lỗi
TypeError
, cho biết rằng hàmtinh_lai_suat()
đã nhận được các đối số positional-only (ở đây làso_tien
vàlai_suat
) thông qua các từ khóa (keyword arguments), điều này không được phép.
Ví dụ 3
Một hàm trong Python có thể được thiết kế để sử dụng đồng thời các loại đối số khác nhau: positional-only arguments, positional arguments thông thường và keyword-only arguments. Hãy xem xét ví dụ sau:
def ham_ket_hop(x, /, y, *, z):
print (x, y, z)
ham_ket_hop(10, y=20, z=30)
ham_ket_hop(10, 20, z=30)
Khi thực thi đoạn code trên, kết quả hiển thị như sau:
10 20 30
10 20 30
Giải thích code:
def ham_ket_hop(x, /, y, *, z):
: Câu lệnh này định nghĩa một hàm có tênham_ket_hop
với ba đối số:x
là một đối số chỉ nhận vị trí (positional-only argument), được đánh dấu bằng dấu gạch chéo/
ngay sau nó. Điều này có nghĩa làx
phải được truyền vào hàm theo vị trí và không thể gán giá trị bằng từ khóa.y
là một đối số positional thông thường. Giá trị củay
có thể được truyền vào hàm theo vị trí hoặc bằng cách sử dụng từ khóa.z
là một đối số chỉ nhận từ khóa (keyword-only argument), được đánh dấu bằng dấu sao*
ngay trước nó. Điều này có nghĩa làz
phải được gán giá trị bằng từ khóa khi gọi hàm.print (x, y, z)
: Hàm này sẽ in ra giá trị của ba đối sốx
,y
vàz
ra màn hình.ham_ket_hop(10, y=20, z=30)
: Trong lần gọi hàm này, chúng ta thấy:x
được truyền vào là 10 theo vị trí.y
được truyền vào là 20 bằng từ khóa.z
được truyền vào là 30 bằng từ khóa.
ham_ket_hop(10, 20, z=30)
: Trong lần gọi hàm này:x
được truyền vào là 10 theo vị tríy
được truyền vào là 20 theo vị trí.z
được truyền vào là 30 bằng từ khóa.
Lời kết
Vậy là chúng ta đã tìm hiểu về Positional Only Arguments trong Python, từ định nghĩa cơ bản đến cách ứng dụng thực tế. Hiểu rõ về tính năng này không chỉ giúp bạn viết code tốt hơn mà còn giúp bạn có cái nhìn sâu hơn về ngôn ngữ lập trình Python. Mong rằng thông tin này sẽ hữu ích cho công việc của bạn.