Trong bài viết này, chúng ta sẽ tìm hiểu về *args và **kwargs, hai ký hiệu Python đặc biệt mà bạn có thể đã gặp trong một số chữ ký hàm trước đây
Họ làm gì?
Chúng tôi sẽ trả lời những câu hỏi này. 📚
Số đối số biến trong các hàm PythonTiêu đề là một loại spoiler. *args và **kwargs cho phép bạn chuyển một số lượng đối số khác nhau cho hàm của mình. Nhưng chúng ta sẽ đạt được điều đó
Hiện tại, hãy xem xét một số chức năng phổ biến có tính linh hoạt này và hãy nghĩ xem bạn cũng có thể hưởng lợi như thế nào từ nó
Nếu bạn đã quen với ngôn ngữ lập trình Python, chắc hẳn bạn đã biết 2 hàm sau
1 — Chức năng
import ospath1 = os.path.join["/"]9 tích hợp nổi tiếng
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Như tên đã chỉ ra rõ ràng, chức năng này in dữ liệu ra đầu ra tiêu chuẩn. Nhưng bạn có biết rằng nó cũng có thể nhận bất kỳ số lượng đối số nào [để in] không?
print["hello"]
# helloprint["hello", "there"]
# hello thereprint["I", "have", 5, "dollars"]
# I have 5 dollarsprint["a", 2, [1, 2, 3]]
# a 2 [1, 2, 3]...
2 — Hàm
def multiply_numbers[n1, n2]:
product = n1 + n2
return product
0 từ mô-đun def multiply_numbers[n1, n2]:
product = n1 + n2
return product
1Hàm này tham gia một số đường dẫn tùy ý trên hệ thống tệp. Tương tự như vậy, nó chấp nhận một số lượng đường dẫn thay đổi làm đối số
import ospath1 = os.path.join["/"]
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Sử dụng một hàm chấp nhận số lượng đối số thay đổi có thể rất hữu ích. điều này mang lại rất nhiều tính linh hoạt và giảm sự lộn xộn trong chữ ký hàm. Bên cạnh đó, nó không đưa ra bất kỳ giả định nào về số lượng đối số cần thiết, điều này có thể phù hợp trong nhiều tình huống
Có nhiều tình huống mà bạn cần sử dụng một hàm có số lượng đối số thay đổi
Hãy lấy một ví dụ. hãy tưởng tượng rằng bạn muốn xây dựng một hàm tính toán tập hợp số [giá trị trung bình, tổng, phép nhân, v.v. ] trên một số.
Xem xét phép nhân cho đơn giản [áp dụng tương tự cho các tập hợp khác].
Nếu bạn muốn xác định một hàm nhân hai số, bạn chỉ cần làm như thế này
def multiply_numbers[n1, n2]:
product = n1 + n2
return product
Điều này hoạt động tốt nhưng thay vào đó nhân ba số thì sao?
Một giải pháp tự nhiên mà bạn có thể nghĩ đến là đưa tất cả các số vào một danh sách và chuyển nó vào hàm
def multiply_numbers[list_of_numbers]:
product = 1
for number in list_of_numbers:
product *= number
return product
Mặc dù giải pháp này hiệu quả nhưng nó có thể hơi bất tiện và không linh hoạt nếu bạn không biết trước tất cả các yếu tố có trong danh sách của mình. Bên cạnh đó, nó buộc bạn phải tạo một đối tượng danh sách có vẻ không cần thiết
Truyền đối số không phải từ khóa bằng *args* lập luận. bạn có thể đã thấy đối số kỳ lạ này được sử dụng trong các hàm trước đây nhưng bạn chưa bao giờ hiểu nó là gì
Chà, sử dụng *args trong một hàm là cách Python nói rằng cái này sẽ
- Chấp nhận một số đối số tùy ý
- Đóng gói các đối số nhận được trong một bộ có tên là args. Lưu ý rằng args chỉ là một cái tên và bạn có thể sử dụng bất cứ thứ gì bạn muốn để thay thế. [chúng ta sẽ xem một ví dụ bên dưới]
Hãy ném một số mã để làm cho mọi thứ rõ ràng
Hãy xác định một hàm gói đối số trong một biến args và in cái này ra bàn điều khiển. Không có gì lạ mắt
def my_awesome_function[*args]:
# do awesome job!
print[args]
Nếu chúng ta chuyển một số đối số tùy ý
________số 8chúng ta sẽ thấy rõ rằng tất cả chúng thực sự được đóng gói trong một bộ
Ngay cả khi chúng tôi không vượt qua bất kỳ đối số nào,
my_awesome_function[]
[]
chúng tôi vẫn nhận được một tuple [trống]
Điều này có thể khiến một số người hơi khó chịu một chút, nhưng bạn thậm chí có thể đóng gói nhiều đối số thuộc các loại khác nhau
print["hello"]0
# helloprint["hello", "there"]
# hello thereprint["I", "have", 5, "dollars"]
# I have 5 dollarsprint["a", 2, [1, 2, 3]]
# a 2 [1, 2, 3]...
Toán tử * làm gì?
Đây là toán tử giải nén. Nó xuất hiện trước một lần lặp [e. g. một danh sách hoặc một bộ] và những gì nó thực sự làm là trải rộng phần tử của nó dưới dạng các đối số của hàm. Về cơ bản nó là một ký hiệu nơi.
print["hello"]1
# helloprint["hello", "there"]
# hello thereprint["I", "have", 5, "dollars"]
# I have 5 dollarsprint["a", 2, [1, 2, 3]]
# a 2 [1, 2, 3]...
tương đương với
print["hello"]2
# helloprint["hello", "there"]
# hello thereprint["I", "have", 5, "dollars"]
# I have 5 dollarsprint["a", 2, [1, 2, 3]]
# a 2 [1, 2, 3]...
Bây giờ, quay lại ví dụ trước về phép nhân, chúng ta có thể viết lại hàm bằng cách sử dụng đóng gói
import ospath1 = os.path.join["/"]0
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Hàm này hiện có thể nhận số lượng đối số tùy ý và ngay cả khi bạn có một danh sách các số, bạn vẫn có thể sử dụng nó. đây là nơi giải nén hữu ích
import ospath1 = os.path.join["/"]1Truyền đối số từ khóa với **kwargs
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Trước hết, đối số từ khóa là gì?
Khi bạn định nghĩa một hàm như sau
import ospath1 = os.path.join["/"]2
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Bạn có thể gọi nó theo hai cách khác nhau, bằng cách
1 — Truyền đối số vị trí
import ospath1 = os.path.join["/"]3
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
2 — hoặc truyền đối số từ khóa [hoặc được đặt tên]
import ospath1 = os.path.join["/"]4
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Như bạn mong đợi, Python cũng có cách truyền đối số từ khóa có độ dài thay đổi [hoặc đối số được đặt tên] theo cách riêng của nó. điều này đạt được bằng cách sử dụng biểu tượng **kwargs
Khi sử dụng **kwargs, tất cả các đối số từ khóa bạn chuyển đến hàm được đóng gói bên trong một từ điển. Và, như bạn mong đợi, biến từ điển này được gọi là kwargs
Hãy xem một ví dụ nhỏ sử dụng **kwargs. Một ví dụ đơn giản nhận các đối số từ khóa và in các cặp khóa-giá trị của chúng
import ospath1 = os.path.join["/"]5Làm việc với *args và **kwargs
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Bây giờ bạn đã hiểu những điều cơ bản của hai ký hiệu này, có một số quy tắc cụ thể áp dụng cho chúng
- Bạn có thể sử dụng *args với các đối số vị trí. Trong ngữ cảnh này, *args phải ở cuối
import ospath1 = os.path.join["/"]6
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
- Nếu chúng ta thêm một đối số vị trí có giá trị mặc định vào ví dụ trước, thì đối số này phải ở cuối
import ospath1 = os.path.join["/"]7
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
- Bạn có thể kết hợp *args với **kwargs và thậm chí thêm đối số vị trí với giá trị mặc định. Trong trường hợp đó, thứ tự là. *args, đối số vị trí với giá trị mặc định, **kwargs
import ospath1 = os.path.join["/"]8Kết luận
path2 = os.path.join["/", "Users"]
path3 = os.path.join["/", "Users", "Library"]# ...
Hãy kết thúc nó
- *args và **kwargs cho phép bạn có các đối số có độ dài thay đổi
- *args cho phép bạn chuyển một số lượng biến đối số không phải từ khóa được đóng gói thành một bộ
- **kwargs cho phép bạn chuyển một số đối số từ khóa khác nhau được đóng gói vào một từ điển
- *args và **kwargs làm cho mã của bạn linh hoạt hơn
- *args và **kwargs có thể được kết hợp cùng với các đối số vị trí
Nếu bạn muốn tìm hiểu sâu hơn về chủ đề *args và **kwargs, bạn có thể xem các tài nguyên sau
- https. // stackoverflow. com/questions/33542959/why-use-packed-args-kwargs-instead-of-passing-list-dict
- https. //www. hướng dẫn python. net/python-cơ bản/python-args/
- https. // treyhunner. com/2018/04/keyword-arguments-in-python/#What_are_keyword_arguments?
- https. // hướng tới khoa học dữ liệu. com/10-ví dụ-to-master-args-and-kwargs-in-python-6f1e8cc30749
Một lần nữa, nếu bạn đã làm được đến đây, tôi xin cảm ơn bạn đã dành thời gian và hy vọng rằng bạn đã học được điều gì đó hữu ích để làm cho mã của bạn sạch hơn và linh hoạt hơn