*args , **kwargs ในภาษา Python คือ อะไร ??
โดยทั่วไปการเขียนโปรแกรมมักจะมีการแยกการทำงานต่าง ๆ ออกเป็น function เพื่อให้ code ดูเป็นระเบียบ เมื่อต้องมีการกลับมาแก้ไขภายหลังก็สามารถทำได้ง่าย
ตัวอย่างเช่น ฟังก์ชันการหาผลบวกตัวเลข
def my_add(x, y) :
return x + y
print(my_add(2,3)) # 5
จาก code ด้านบน ฟังก์ชันสามารถหาผลรวมของเลข สองจำนวน (เพราะว่าเรารับ 2 argument คือ x และ y) แต่ถ้าหากว่าเราต้องการหาผลรวมของตัวเลขโดยที่เราไม่รู้ว่าจะมีกี่จำนวนกันแน่ เราสามารถทำแบบนี้ได้
def my_add(*args) :
total = 0
for i in args :
total += i
return total
print(my_add(2,3)) # 5
print(my_add(2,3,4)) # 9
*args จะเป็นการรับ argument ที่ไม่รู้จำนวนที่แน่นอน เป็น tuple ซึ่งเราจะส่งไปกี่จำนวนก็ได้
สำหรับ **kwargs นั้นก็มีลักษณะที่คล้าย ๆ กัน คือ จะส่ง argument ที่ไม่ทราบจำนวนที่แน่นอนแต่จะเป็นการส่งแบบ keyword เป็น dictionary เช่น
def my_add(**kwargs) :
total = 0
for k,v in kwargs.items() :
total += v
return total
print(my_add(a=1,b=2)) # 3
print(my_add(a=1,b=2,c=3)) # 6
เราสามารถเอาทั้ง 2 แบบนี้มารวมกันใน function เดียวกันได้เป็นแบบนี้
def my_add(*args, **kwargs) :
total = 0
for i in args :
total += i
for k,v in kwargs.items() :
total += v
return total
print(my_add(1,2,3,a=4,b=5)) # 15
โดยสรุปแล้วก็คือทั้ง *args และ **kwargs จะเป็นการรับ argument โดยที่เราไม่ทราบจำนวน argument ที่แน่นอน
จากตัวอย่างด้านบนจะเรียกวิธีการแบบนี้ว่า Unpacking Arguments
ทั้งนี้ สามารถที่จะส่งค่าเป็นตัวแปรให้ function เลยก็ได้ จะเป็นการกระจายทุกค่าในตัวแปรนั้น ๆ โดยจะใช้ operator * (สำหรับ range ,list , tuple) และ ** (สำหรับ dictionary)
def my_add(*args, **kwargs) :
total = 0
for i in args :
total += i
for k,v in kwargs.items() :
total += v
return total
a = range(1,4) # <class 'range'>
b = list(a) # <class 'list'>
c = tuple(a) # <class 'tuple'>
d = {'a':4,'b':5} # <class 'dict'>
print(my_add(*a,**d)) # 15
print(my_add(*b,**d)) # 15
print(my_add(*c,**d)) # 15