Hướng dẫn dùng args r python

Trong bài này mình sẽ giới thiệu hai loại tham số mà nhiều bạn không biết đến, đó là *args**kwargs. Đây là hai tham số đặc biệt được dùng trong trường hợp bạn không chắc chắn số lượng tham số sẽ truyền vào hàm.

Hướng dẫn dùng args r python

Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Trong Python, chúng ta có thể truyền một số lượng biến vào tham số của hàm bằng cách sử dụng ký hiệu đặc biệt như:

  • *args (Non-Keyword Arguments)
  • **kwargs (Keyword Arguments)

Ta sử dụng *args*kwargs để làm đối số truyền vào hàm trong trường hợp không chắc chắn sẽ có bao nhiêu tham số sẽ truyền vào.

Và lưu ý rằng việc đặt tên là args hay kwargs chỉ là quy ước, nên bạn có thể đặt một cái tên khác bất kì, miễn là có sử dụng các dấu ngôi sao.

Bài viết này được đăng tại [free tuts .net]

1. *args trong Python

*args được dùng trong trường hợp truyền tham số vào hàm là những giá trị không có key.

Ví dụ 1: In ra xem *args có gì đặc biệt

def test(*args):
    print(args)

test(1,2,3)

Kết quả khi print(args) thì nó là một tuple, như vậy ta không thể thay đổi giá trị cho các phần tử của args.

Vì là một tupe nên bạn có thể sử dụng những phép toán thường dùng trên tuple như: Sử dụng vòng lặp để duyệt qua các phần tử, kiểm tra một giá trị có xuất hiện trong args không ...

Ví dụ 2: Viết chương trình trả về tổng của các phần tử truyền vào.

def calSum(*args):
    tong = 0
    for item in args:
        tong += item
    return tong

print(calSum(1,2)) # 3
print(calSum(1,2,3,4,5,6)) # 21

Kết quả:

2. **kwargs trong Python

**kwargs được dùng trong trường hợp truyền tham số vào hàm sẽ là cặp giá trị key = value.

Ví dụ 1: In ra xem **kwargs có gì đặc biệt nhé.

def showInfor(**kwargs):
    print(kwargs)

showInfor(domain = "freetuts.net", author = 'Nguyễn Văn Cường')

Kết quả:

Như vậy kết quả khi ta print(kwargs) thì nó là một dict, vì vậy ta có thể thay đổi giá trị của các phần tử kwargs.

Ngoài ra, vì nó là một dict nên ta có thể sử dụng hầu hết các phép tính liên quan đến dict trên kwargs.

Ví dụ 2: In ra thông tin cá nhân của chủ của một website.

def showInfor(**kwargs):
    for item in kwargs.items():
        print(item[0], ' = ' , item[1])

showInfor(domain = "freetuts.net", author = 'Nguyễn Văn Cường')

Kết luận: Như vậy là mình đã hướng dẫn xong cách sử dụng *args và **kwargs trong Python.

Qua bài này bạn cần nắm vững những thông tin như sau:

  • *args dùng trong trường hợp chỉ truyền vào tham số là giá trị, còn **kwargs là dạng key = value
  • *args là Tuple, còn **kwargs là Dict.

Câu hỏi thường gặp liên quan:

  • Cách tính căn bậc hai trong Python với hàm sqrt
  • Yield trong Python dùng để làm gì?
  • *args và **kwargs trong Python dùng để làm gì?

Cùng chuyên mục:

Dẫn nhập

Functions là cuộc sống, đúng không? nếu bạn là người mới vào học Python - là lính mới hay nhảy qua từ ngôn ngữ khác  - bạn học về số lượng tham số trong định nghĩa function khi đúng toàn bộ tham số thì mới tiếp tục.

Đó là nền tảng - thứ giúp chúng ta hiểu rõ từ bên ngoài. Tuy nhiên, nó cũng làm cho các bạn khá choáng váng khi bạn thấy *args hoặc **kwargs trong định nghĩa function.

Đừng để cú pháp làm sợ bạn. Nó không phải là những tham số đặc biệt thần thánh. Nó còn thậm chí không quá ảo, và chúng ta sẽ học cách sử dụng nó.


Tham số vị trí vs Tham số từ khóa

Có 2 khái niệm chúng ta cần phải tách ra nhằm để học*args**kwargs là gì.

Đầu tiên là khác nhau giữa tham số vị trí tham số từ khóa (Keyword). Ở những function cơ bản nhất, chúng ta chơi trò ghép cặp - đối số 1 sẽ đến tham số 1, đối số 2 đến tham số, và tiếp tục.

def printThese(a,b,c):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2,3)
"""
1 is stored in a
2 is stored in b
3 is stored in c
"""

Lưu ý: Tất cả đối số phải có. Thiếu một sẽ gây ra lỗi.

def printThese(a,b,c):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2)
"""
TypeError: printThese() missing 1 required positional argument: 'c'
"""

Nếu chúng ta cho giá trị mặc định cho tham số trong định nghĩa function, thì nó trở thành không bắt buộc

def printThese(a,b,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2)
"""
1 is stored in a
2 is stored in b
None is stored in c
"""

Ngoài ra, tham số không bắt buộc sẽ trở thành keyword-eligible(từ khóa điều kiện), nghĩa là bạn có thể ghi rõ tên tham số khi gọi function để gán giá trị phù hợp.

Hãy gán 3 tham số có giá trị mặc định None và sẽ cách chúng ta gán giá trị không cần sắp xếp.

def printThese(a=None,b=None,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(c=3, a=1)
"""
def printThese(a=None,b=None,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(c=3, a=1)
"""
1 is stored in a
None is stored in b
3 is stored in c
"""

Toán tử Splat

Để tôi bắt đầu nói tôi yêu thích tên toán tử này - nó rất là … trực quan. * là  ký hiệu phổ biến nhất về phép nhân, nhưng ở Python nó còn có nghĩa toán tử Splat.

Tôi nghĩa toán tử này như cái hộp piñata - cái hộp nhét bánh kẹo vào trong rồi người ta dùng gậy đập tung nó ra. Tôi đã từng mô tả về toán tử mở rộng - một cái tương đương splat của JavaScript - nó giải nén một chuỗi domino rồi đẩy và một danh sách đơn lớn hơn, nhưng splat bảo đảm tương tự một cái mạnh mẽ hơn.

Một ví dụ cơ bản để bạn hiểu rõ hơn.

a = [1,2,3]
b = [*a,4,5,6]
print(b) # [1,2,3,4,5,6]

Trong ví dụ trên, chúng ta mang dữ liệu của a và giải nén đẩy vào toàn bộ list b.


Cách sử dụng *args và **kwargs

Vậy chúng ta đã biết toán tử splat giải nén toàn bộ dữ liệu có kí hiệu *, và có 2 loại tham số function. Vậy, nếu bạn chưa phát hiện ra, *args là viết tắt của (arguments) đối số, **kwargs là viết tắt của (keyword arguments) đối số từ khóa.

Nó được sử dụng để giải nén ra loại đối số tương ứng, cho phép gọi function có list đối số có số lượng giá trị thay đổi. Ví dụ, tạo một function in ra các điểm kiểm tra.

def printScores(student, *scores):
   print(f"Student Name: {student}")
   for score in scores:
      print(score)
printScores("Jonathan",100, 95, 88, 92, 99)
"""
Student Name: Jonathan
100
95
88
92
99
"""

Ủa khoan đã!!! Tôi không đặt tên *args? Đúng rồi, “args” chỉ là quy ước tiêu chuẩn nhưng vẫn chỉ là tên gọi.  Bí mật đã được bật mí, trong *args, dấu * thực sự là dân chơi, tạo 1 list mà toàn bộ giá trị là những đối số tương ứng khi gọi function.

Điều đó đã rõ ràng, **kwargs trở nên sẽ hiểu sâu. Cái tên không quan trọng, ** tạo ra một dictionary mà toàn bộ giá trị là là những đối số từ khóa khi gọi function.

Để minh họa, hãy tạo 1 function và in tên các con vật của người đó.

def printPetNames(owner, **pets):
   print(f"Owner Name: {owner}")
   for pet,name in pets.items():
      print(f"{pet}: {name}")
printPetNames("Jonathan", dog="Brock", fish=["Larry", "Curly", "Moe"], turtle="Shelldon")
"""
Owner Name: Jonathan
dog: Brock
fish: ['Larry', 'Curly', 'Moe']
turtle: Shelldon
"""

Lưu ý

Một vài lời khôn ngoan sẽ giúp bạn tránh lỗi thông thường và mở rộng kiến thức của bạn.

  • Sử dụng *args, **kwargs nhưng là quy ước tiêu chuẩn để bắt các đối số vị trí và từ khóa.
  • Bạn không thể đặt **kwargs trước *args, nếu không bạn sẽ nhận lỗi,
  • Cẩn thận việc trùng lặp tham số từ khóa và **kwargs khi giá trị được định nghĩa sẽ nằm ở **kwarg nhưng nó vô tình dính tên của tham số từ khóa.
  • Bạn có thể sử dụng toán tử splat khi gọi function.

Kết

Như vậy chúng ta đã tìm hiểu về *args và **kwargs trong Python là gì? 

Bài viết được dịch từ Medium.com. Bạn có thể tham khảo bài viết gốc tại đây: What Are *args and **kwargs in Python?

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.