การใช้งาน *args และ **kwargs ในภาษา Python

   By: DH Team

   อัปเดตล่าสุด Feb. 1, 2024

การใช้งาน *args และ **kwargs ในภาษา Python

สำหรับคำสั่ง *args และ **kwargs ในภาษา Python ผมเชื่อว่าเพื่อน ๆ ที่ศึกษาภาษา Python ต้องเจอมาแล้วกันทุกคนเป็นอย่างแน่นอน แต่มันคืออะไร ใช้ยังไง ใช้ตอนไหน เดี๋ยววันนี้มา recap กัน
จากโค้ดด้านล่าง ฟังก์ชัน hello_world()  คือการประกาศฟังก์ชันแบบปกติ จะเห็นว่าไม่มีอะไรอยู่ในวงเล็บหรือประกาศพารามิเตอร์ใด ๆ ไว้ แบบนี้เราไม่ต้องส่งอากิวเมนต์ใด ๆ เข้าไปในฟังก์ชัน จะเห็นว่าโค้ดบรรทัดสุดท้ายในฟังก์ชันก็ว่างเปล่าได้เลย

def hello_world():
print("Hello world, you all Python guys !!")

hello_world() # ฟังก์ชันปกติ ไม่ต้องส่งอากิวเมนต์ใด ๆ เข้าไป


Output
Hello world, you all Python guys !!


Parameter vs Argument


ทีนี้มาดูฟังก์ชันแบบที่มี Parameter และ Argument กันครับ

จากโค้ดด้านล่าง

  • พารามิเตอร์: param1 , param2 (ตัวแปรที่ประกาศไว้ในฟังก์ชัน)
  • อากิวเมนต์: 1, 2 (ข้อมูลที่ส่งเข้าไปในฟังก์ชันตามจำนวนพารามิเตอร์ที่ประกาศไว้)
def sum_num(param1, param2):
sum = param1 + param2
return sum

print(sum_num(2, 3)) # ส่งอากิวเมนต์เข้ามาตามพารามิเตอร์ที่ได้ประกาศไว้


Output

5

จากฟังก์ชัน sum_num(...) ประกาศพารามิเตอร์ไว้สองตัว คือ param1 และ param2 โดยในฟังก์ชันนี้ก็ไม่ได้มีอะไรมาก นำพารามิเตอร์ 2 ตัวนี้มาบวกกันและเก็บไว้ในตัวแปร sum  ซึ่งก็จะได้ 2 + 3 ผลลัพธ์คือ 5 นั่นเอง
แต่ถ้าประกาศพารามิเตอร์ไว้ในฟังก์ชัน แต่ส่งอากิวเมนต์เข้ามาไม่ครบ ?

def sum_num(param1, param2):
sum = param1 + param2
return sum

print(sum_num(2))


จะได้ error แบบนี้ นั่นก็คือเราประกาศพารามิเตอร์ไว้ 2 ตัวในฟังก์ชันคือ param1 และ param2 แต่ตอนส่งค่าอากิวเมนต์เข้ามา ส่งมาแค่ค่าเดียวคือค่าของ param1 นั่นก็คือ 2

TypeError: sum_num() missing 1 required positional argument: 'param2'

ดังนั้นนี่คือแบบฟิกพารามิเตอร์ เรากำหนดเท่าไหร่ในฟังก์ชัน ก็ต้องส่งค่าหรืออากิวเมนต์เข้ามาให้ครบ (หรือส่งเกินก็ไม่ได้)


*args คืออะไร ?

*args คือ พารามิเตอร์แบบที่ไม่ใช่คีย์เวิร์ด (Non-Keyword Arguments) คือสามารถส่งค่าเข้ามาในฟังก์ชันได้เลย โดยเป็นชนิดข้อมูลแบบ tuple ซึ่งใน *args นั้นจะไม่ได้ฟิกอากิวเมนต์ที่ต้องส่งเข้ามาเหมือนกับพารามิเตอร์ปกติแล้วครับ (จะส่งเข้ามาเท่าไหร่ก็ได้)
ตัวอย่างโค้ด

def hello_guy(*args):
for arg in args:
print(arg)

hello_guy('Hello', 'Mr. Pita', 43) # ส่งเข้ามากี่ตัวก็ได้ (ในตัวอย่างคือ 3 ตัว)



Output

Hello
Mr. Pita
43


จากตัวอย่าง ฟังก์ชัน   hello_guy()  สามารถรับอาร์กิวเมนต์ได้หลายตัว

  • ประกาศฟังก์ชันชื่อ   hello_guy()  พร้อมประกาศพารามิเตอร์  *args
  • ลูป  args ออกมา(เพราะ  *args เป็นประเภทข้อมูลแบบ tuple เลยสามารถรัน for loop ได้เลย)
  • จากนั้น print แสดงผลออกทางหน้าจอ
  • เรียกใช้ฟังก์ชัน โดยในฟังก์ชันรับอากิวเมนต์เข้ามา 3 ตัวคือ   Hello ,  Mr. Pita และ   43 เห็นไหมครับว่าเราจะส่งอากิวเมนต์เข้าไปกี่ตัวก็ได้ในฟังก์ชันนี้


Note: การประกาศแบบ *args นั้นข้อสังเกตง่าย ๆ คือมี * (asterisk) 1 ตัวอยู่ข้างหน้า และไม่ต้องเป็นคำว่า *args แบบนี้ก็ได้จะเป็นคำไหนก็ได้โดยให้ใส่ * เพื่อเป็นตัวบ่งบอก (identifier) แต่แนะนำว่าถ้าไม่จำเป็นก็ให้ใช้ตัวนี้แหละครับเพราะมันคือ convention (ธรรมเนียมที่ปฏิบัติกันมา)


**kwargs คืออะไร ?

**kwargs คือ พารามิเตอร์ที่กำหนดไว้เพื่อใช้ส่งอากิวเมนต์เข้ามาในฟังก์ชันแบบไม่ตายตัว ซึ่งมีความคล้ายกันกับ *args แต่ความต่าง คือ อากิวเมนต์ที่ส่งเข้ามาต้องเป็นแบบคีย์เวิร์ด (Keyword Arguments) อาร์กิวเมนต์เหล่านี้จะถูกรับเข้ามาในฟังก์ชันเป็นแบบ dict ( หรือ dictionary) ซึ่งหมายความว่าเราต้องกำหนด Key ให้กับอากิวเมนต์ด้วย แทนที่จะใส่เฉพาะ Value เพียว ๆ


ตัวอย่างโค้ด

def hello_devhub(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

print(hello_devhub(greeting='Hello', name='Devhub', team_members=3)) # ส่งแบบ key:value

Output

greeting: Hello
name: Devhub
team_members: 3


จากตัวอย่าง ฟังก์ชัน   hello_devhub()  สามารถรับอาร์กิวเมนต์ได้หลายตัว (แต่ต้องกำหนด Keys ของอากิวเมนต์แต่ละตัวด้วย)

  • ประกาศฟังก์ชันชื่อ  hello_devhub()  พร้อมประกาศพารามิเตอร์   **kwargs 
  • ลูป    kwargs   ออกมา (และ  **kwargs เป็นประเภทข้อมูลแบบ dict เลยสามารถรัน for loop ได้เลย) โดยเราสามารถ loop ออกมาได้ทั้ง key และ value ของ Dict โดยดึงค่าออกมาด้วยเมธอด  .items() ซึ่งเป็นหนึ่ง built-in function ของ dict (มีให้อ่านต่อด้านล่าง)
  • จากนั้น print แสดงผลออกทางหน้าจอ
  • เรียกใช้ฟังก์ชัน โดยในฟังก์ชันรับอากิวเมนต์เข้ามา 3 ตัวคือ greeting="Hello"        name="Dehub"    และ    team_members=3     

ใจความสำคัญอยู่ที่บรรทัดสุดท้าย จะเห็นว่า  **kwargs นั้นเราต้องใส่ข้อมูลที่เป็นแบบ key:value ซึ่งมันก็คือ Dict นั่นเอง


Note: การประกาศแบบ **kwargs นั้นมีข้อสังเกตง่าย ๆ คือมี ** (asterisks) 2 ตัวอยู่ข้างหน้า และเช่นเดียวกัย *args คือไม่ฟิกตายตัวว่าต้องเป็น **kwargs

สำหรับผู้อ่านที่อยากศึกษาเพิ่มเติมเกี่ยวกับ built-in methods ของ Dict ว่ามีตัวไหนบ้าง ผมก็แนะนำ Python Dictionary - W3schools เลยครับ

Python Dictionary Built-in Methods


การใช้งานร่วมกันระหว่าง *args และ **kwargs

*args และ **kwargs สามารถใช้งานร่วมกันได้ในฟังก์ชันเดียวกัน เพื่อให้ฟังก์ชันนั้นสามารถรับอาร์กิวเมนต์ได้ทั้งแบบไม่มีคีย์เวิร์ดและแบบมีคีย์เวิร์ด
ตัวอย่างโค้ด

def combine_params(*args, **kwargs):
for arg in args:
print(arg)
for key, value in kwargs.items():
print(f"{key}: {value}")

combine_params('apple', 'banana', first='orange', second='grape')


ในฟังก์ชัน  combine_2_params(...)  เป็นการรวมการประกาศพารามิเตอร์ทั้งแบบ *args และ **kwargs เข้ามาใข้งานร่วมกัน

Output

apple
banana
first: orange
second: grape


สรุป


  • *args คือ พารามิเตอร์ที่ประกาศไว้ในฟังก์ชัน โดยที่ไม่ได้กำหนดอากิวเมนต์ (ข้อมูลที่ส่งเข้ามา) แบบตายตัว สามารถส่งเข้ามาในฟังก์ชันกี่ตัวก็ได้ เป็นประเภทข้อมูลแบบ Tuple
  • **kwargs คือ พารามิเตอร์ที่ประกาศไว้ในฟังก์ชัน คล้ายกันกับ **args เพียงแต่ว่าข้อมูลที่ส่งเข้ามาต้องกำหนดคีย์ของข้อมูลนั้นด้วย เป็นประเภทข้อมูลแบบ Dict (Dictionary)
    โดยทั้ง *args และ **kwargs นั้นช่วยทำให้ฟังก์ชันของเรายืดหยุ่นได้เป็นอย่างดี


หวังว่าบทความนี้จะช่วย recap ให้เพื่อน ๆ ได้เข้าใจเกี่ยวกับโครงสร้างและการใช้งาน *args และ **kwargs ในภาษา Python กันมากขึ้นไม่มากก็น้อย ถ้าเห็นคำสั่งนี้แล้วต่อไปก็ไม่ต้องตกใจ และสามารถใช้มันได้อย่างถูกต้องและไม่งงกันครับ ... Happy coding ครับ

เพิ่มเพื่อนใน LINE Official ของ devhub.in.th เพื่อที่จะได้ไม่พลาดทุก ๆ event แจ่ม ๆ ที่จะถึงก่อนใคร


เปิดโลกการเขียนโปรแกรมและ Software Development ด้วย online courses ที่จะพาคุณอัพสกิลและพัฒนาสู่การเป็นมืออาชีพ เรียนออนไลน์ เรียนจากที่ไหนก็ได้ พร้อมซัพพอร์ตหลังเรียน

คอร์สเรียนเขียนโปรแกรม