Cách sử dụng * args và ** kwargs trong Python 3
Trong định nghĩa hàm , các tham số là các thực thể được đặt tên chỉ định một đối số mà một hàm đã cho có thể chấp nhận. Khi lập trình, bạn có thể không nhận thức được tất cả các trường hợp sử dụng có thể có của mã của bạn và có thể cần cung cấp nhiều tùy chọn hơn cho các lập trình viên tương lai làm việc với module hoặc cho user tương tác với mã. Ta có thể truyền một số lượng biến đối số cho một hàm bằng cách sử dụng *args
và **kwargs
trong mã của ta .
Hiểu biết * args
Trong Python, dạng dấu hoa thị đơn của *args
được dùng làm tham số để gửi danh sách đối số có độ dài biến không có từ khóa đến các hàm. Cần lưu ý dấu hoa thị ( *
) là yếu tố quan trọng ở đây, vì từ args
là thành ngữ truyền thống đã được cài đặt , mặc dù nó không được ngôn ngữ thực thi.
Hãy xem xét một hàm điển hình sử dụng hai đối số:
def multiply(x, y): print (x * y)
Trong đoạn mã trên, ta đã xây dựng hàm với x
và y
là các đối số, và sau đó khi ta gọi hàm, ta cần sử dụng các số tương ứng với x
và y
. Trong trường hợp này, ta sẽ chuyển số nguyên 5
vào cho x
và số nguyên 4
cho y
:
def multiply(x, y): print (x * y) multiply(5, 4)
Bây giờ, ta có thể chạy đoạn mã trên:
- python lets_multiply.py
Ta sẽ nhận được kết quả sau, cho thấy rằng các số nguyên 5 và 4 đã được nhân theo hàm multiply(x,y)
:
Output20
Điều gì sẽ xảy ra nếu sau này, ta quyết định rằng ta muốn nhân ba số thay vì chỉ nhân hai? Nếu ta cố gắng thêm một số bổ sung vào hàm, như được hiển thị bên dưới, ta sẽ nhận được lỗi.
def multiply(x, y): print (x * y) multiply(5, 4, 3)
OutputTypeError: multiply() takes 2 positional arguments but 3 were given
Vì vậy, nếu bạn nghi ngờ rằng bạn có thể cần sử dụng nhiều đối số hơn sau này, bạn có thể sử dụng *args
làm tham số của bạn .
Về cơ bản, ta có thể tạo cùng một hàm và mã mà ta đã trình bày trong ví dụ đầu tiên, bằng cách loại bỏ x
và y
làm tham số hàm và thay vào đó thay chúng bằng *args
:
def multiply(*args): z = 1 for num in args: z *= num print(z) multiply(4, 5) multiply(10, 9) multiply(2, 3, 4) multiply(3, 5, 10, 6)
Khi ta chạy mã này, ta sẽ nhận được sản phẩm cho từng lệnh gọi hàm sau:
Output20 90 24 900
Bởi vì ta đã sử dụng *args
để gửi một danh sách đối số có độ dài thay đổi đến hàm của ta , ta có thể chuyển nhiều đối số tùy thích vào các lệnh gọi hàm.
Với *args
bạn có thể tạo mã linh hoạt hơn chấp nhận một lượng lớn các đối số không có từ khóa trong hàm của bạn.
Hiểu biết ** kwargs
Dạng dấu hoa thị kép của **kwargs
được sử dụng để chuyển từ điển đối số có từ khóa, độ dài thay đổi vào một hàm. , hai dấu hoa thị ( **
) là yếu tố quan trọng ở đây, vì từ kwargs
được sử dụng thông thường, mặc dù không được ngôn ngữ thực thi.
Giống như *args
, **kwargs
có thể có nhiều đối số mà bạn muốn cung cấp cho nó. Tuy nhiên, **kwargs
khác với *args
ở chỗ bạn cần phải chỉ định các từ khóa.
Đầu tiên, ta chỉ cần in ra các đối số **kwargs
mà ta truyền cho một hàm. Ta sẽ tạo một hàm ngắn để thực hiện việc này:
def print_kwargs(**kwargs): print(kwargs)
Tiếp theo, ta sẽ gọi hàm với một số đối số có từ khóa được truyền vào hàm:
def print_kwargs(**kwargs): print(kwargs) print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)
Hãy chạy chương trình trên và xem kết quả:
- python print_kwargs.py
Output{'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}
Tùy thuộc vào version Python 3 mà bạn hiện đang sử dụng, kiểu dữ liệu từ điển có thể không có thứ tự. Trong Python 3.6 trở lên, bạn sẽ nhận được các cặp key-value theo thứ tự, nhưng trong các version trước đó, các cặp sẽ được xuất theo thứ tự ngẫu nhiên.
Điều quan trọng cần lưu ý là một từ điển có tên là kwargs
được tạo ra và ta có thể làm việc với nó giống như ta có thể làm việc với các từ điển khác.
Hãy tạo một chương trình ngắn khác để chỉ ra cách ta có thể sử dụng **kwargs
. Ở đây ta sẽ tạo một hàm để chào một từ điển tên. Đầu tiên, ta sẽ bắt đầu với một từ điển gồm hai tên:
def print_values(**kwargs): for key, value in kwargs.items(): print("The value of {} is {}".format(key, value)) print_values(my_name="Sammy", your_name="Casey")
Bây giờ ta có thể chạy chương trình và xem kết quả:
- python print_values.py
OutputThe value of your_name is Casey The value of my_name is Sammy
, vì từ điển có thể không có thứ tự, kết quả của bạn có thể có tên Casey
trước hoặc với tên Sammy
trước.
Bây giờ ta hãy chuyển các đối số bổ sung cho hàm để cho thấy rằng **kwargs
sẽ chấp nhận tuy nhiên nhiều đối số bạn muốn đưa vào:
def print_values(**kwargs): for key, value in kwargs.items(): print("The value of {} is {}".format(key, value)) print_values( name_1="Alex", name_2="Gray", name_3="Harper", name_4="Phoenix", name_5="Remy", name_6="Val" )
Khi ta chạy chương trình tại thời điểm này, ta sẽ nhận được kết quả sau, kết quả này có thể lại không có thứ tự:
OutputThe value of name_2 is Gray The value of name_6 is Val The value of name_4 is Phoenix The value of name_5 is Remy The value of name_3 is Harper The value of name_1 is Alex
Sử dụng **kwargs
cung cấp cho ta sự linh hoạt để sử dụng các đối số từ khóa trong chương trình của ta . Khi ta sử dụng **kwargs
làm tham số, ta không cần biết có bao nhiêu đối số mà cuối cùng ta muốn truyền cho một hàm.
Thứ tự đối số
Khi sắp xếp thứ tự các đối số trong một hàm hoặc lệnh gọi hàm, các đối số cần phải xảy ra theo một thứ tự cụ thể:
- Đối số vị trí chính thức
-
*args
- Đối số từ khóa
-
**kwargs
Trong thực tế, khi làm việc với các tham số vị trí rõ ràng cùng với *args
và **kwargs
, hàm của bạn sẽ giống như sau:
def example(arg_1, arg_2, *args, **kwargs): ...
Và, khi làm việc với các tham số vị trí cùng với các tham số từ khóa được đặt tên ngoài *args
và **kwargs
, hàm của bạn sẽ trông giống như sau:
def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs): ...
Điều quan trọng là phải ghi nhớ thứ tự của các đối số khi tạo các hàm để bạn không nhận được lỗi cú pháp trong mã Python của bạn .
Sử dụng * args và ** kwargs trong lệnh gọi hàm
Ta cũng có thể sử dụng *args
và **kwargs
để truyền các đối số vào các hàm.
Đầu tiên, hãy xem một ví dụ với *args
.
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) args = ("Sammy", "Casey", "Alex") some_args(*args)
Trong hàm trên, có ba tham số được định nghĩa là arg_1
, arg_
và arg_3
. Hàm sẽ in ra từng đối số này. Sau đó, ta tạo một biến được đặt thành có thể lặp lại (trong trường hợp này là bộ tuple ) và có thể chuyển biến đó vào hàm bằng cú pháp dấu hoa thị.
Khi ta chạy chương trình bằng lệnh python some_args.py
, ta sẽ nhận được kết quả sau:
Outputarg_1: Sammy arg_2: Casey arg_3: Alex
Ta cũng có thể sửa đổi chương trình ở trên thành kiểu dữ liệu danh sách có thể lặp lại với một tên biến khác. Hãy cũng kết hợp cú pháp *args
với một tham số có tên :
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) my_list = [2, 3] some_args(1, *my_list)
Nếu ta chạy chương trình trên, nó sẽ tạo ra kết quả sau:
Outputarg_1: 1 arg_2: 2 arg_3: 3
Tương tự, các đối số **kwargs
có từ khóa được dùng để gọi một hàm. Ta sẽ cài đặt một biến tương đương với một từ điển với 3 cặp key-value ( ta sẽ sử dụng kwargs
ở đây, nhưng nó có thể được gọi là bạn muốn ) và chuyển nó vào một hàm có 3 đối số:
def some_kwargs(kwarg_1, kwarg_2, kwarg_3): print("kwarg_1:", kwarg_1) print("kwarg_2:", kwarg_2) print("kwarg_3:", kwarg_3) kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3": "Remy"} some_kwargs(**kwargs)
Hãy chạy chương trình ở trên với lệnh python some_kwargs.py
:
Outputkwarg_1: Val kwarg_2: Harper kwarg_3: Remy
Khi gọi một hàm, bạn có thể sử dụng *args
và **kwargs
để chuyển đối số.
Kết luận
Ta có thể sử dụng cú pháp đặc biệt của *args
và **kwargs
trong định nghĩa hàm để chuyển một số lượng biến đối số cho hàm.
Việc tạo các hàm chấp nhận *args
và **kwargs
được sử dụng tốt nhất trong các tình huống mà bạn mong đợi rằng số lượng đầu vào trong danh sách đối số sẽ vẫn tương đối nhỏ. Việc sử dụng *args
và **kwargs
chủ yếu để cung cấp khả năng đọc và sự tiện lợi, nhưng cần được thực hiện cẩn thận.
Các tin liên quan
Cách làm việc với control panel tương tác Python2017-06-21
Cách viết câu lệnh có điều kiện trong Python 3
2017-06-16
Cách cài đặt pygame và tạo mẫu để phát triển trò chơi bằng Python 3
2017-06-15
Cách chuyển mã Python 2 sang Python 3
2017-05-17
Cách chuyển mã Python 2 sang Python 3
2017-05-17
Cách sử dụng tính năng ghi log trong Python 3
2017-05-02
Cách gỡ lỗi Python bằng control panel tương tác
2017-04-27
Cách sử dụng trình gỡ lỗi Python
2017-04-25
Cách cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên CentOS 7
2017-04-20
Cách cài đặt Python 3 và thiết lập môi trường lập trình cục bộ trên Debian 8
2017-04-20