Contents

ทำความเข้าใจกับการโอเวอร์โหลดฟังก์ชันใน Python

ฟังก์ชั่นโอเวอร์โหลดเป็นคุณสมบัติในภาษาการเขียนโปรแกรมบางภาษาที่ให้คุณกำหนดรูปแบบต่างๆ ของฟังก์ชันเดียวกันได้ แต่ละตัวแปรมีชื่อเหมือนกัน แต่มีการใช้งานที่แตกต่างกัน พร้อมลายเซ็นฟังก์ชันที่ไม่ซ้ำกัน

วิธีการนี้ช่วยให้สามารถดำเนินการต่างๆ ที่เกิดขึ้นโดยขึ้นอยู่กับลักษณะและปริมาณของพารามิเตอร์ที่ส่งไปยังฟังก์ชัน ทำให้การเขียนโปรแกรมมีความยืดหยุ่นมากขึ้น

Python แตกต่างจากภาษาการเขียนโปรแกรมเช่น C++ และ Java ตรงที่ไม่รองรับฟังก์ชันโอเวอร์โหลดโดยธรรมชาติ อย่างไรก็ตาม เราสามารถจำลองการทำงานนี้ได้ด้วยวิธีอื่น

Python จัดการฟังก์ชั่นโอเวอร์โหลดได้อย่างไร?

ใน Python ฟังก์ชันอาจถูกกำหนดหลายครั้งโดยมีข้อกำหนดพารามิเตอร์และ/หรือประเภทข้อมูลที่แตกต่างกัน อย่างไรก็ตาม เมื่อเรียกใช้ฟังก์ชัน Python จะรับทราบเฉพาะอินสแตนซ์สุดท้ายของคำจำกัดความเท่านั้น มีกรณีตัวอย่างดังนี้

 def arithmetics(a, b):
    return a - b

def arithmetics(a, b, c, d):
    return a \+ b - c * d

print(arithmetics(1, 2, 3, 5)) # returns -12
print(arithmetics(1, 2)) # returns missing positional arguments error

ภาษาการเขียนโปรแกรมเชิงวัตถุ เช่น Java มักรวมกลไกสำหรับการโอเวอร์โหลดฟังก์ชันและเมธอด โดยพื้นฐานแล้ว วิธีการคือฟังก์ชันที่ถูกกำหนดไว้ภายในบริบทของคลาส

ในตัวอย่างโค้ดที่กล่าวมาข้างต้น ล่าม Python จะรับทราบคำจำกัดความที่ประกาศในภายหลังของฟังก์ชัน arithmetic() เมื่อพยายามเรียกใช้ภายในโปรเจ็กต์ หากมีความพยายามเรียกใช้ฟังก์ชันด้วยพารามิเตอร์สองตัวที่สอดคล้องกับการประกาศครั้งแรก ข้อยกเว้นจะปรากฏขึ้นเพื่อระบุว่าอาร์กิวเมนต์ดังกล่าวหายไปและจำเป็นสำหรับการดำเนินการ

/th/images/missing-positional-argument-error.jpg

การเกิดข้อผิดพลาดของฟังก์ชันจะไม่เกิดขึ้นเมื่อมีการระบุพารามิเตอร์สี่ตัวในระหว่างการเรียกใช้ ซึ่งบ่งชี้ว่าฟังก์ชันถูกแทนที่ด้วยเวอร์ชันล่าสุดในหน่วยความจำ อย่างไรก็ตาม นี่ไม่ได้บ่งชี้ถึงการใช้วิธีมากเกินไป และจำเป็นต้องมีแนวทางอื่นในการแก้ปัญหา

Python ไม่รองรับฟังก์ชันโอเวอร์โหลดโดยเนื้อแท้ อย่างไรก็ตาม เราอาจใช้เทคนิคบางอย่างภายในโค้ดเพื่อจำลองการทำงานนี้

วิธีที่ 1: การใช้พารามิเตอร์เสริมหรืออาร์กิวเมนต์เริ่มต้น

เราอาจโอเวอร์โหลดได้สำเร็จโดยการใช้ฟังก์ชันที่มีพารามิเตอร์เริ่มต้น ตัวอย่างสาธิตมีดังนี้:

 def arithmetics(a, b=0, c=0):
    """
    Arguments:
    a: The first number.
    b: The second number (optional).
    c: The third number (optional).
    """
    return a - b \+ c

ฟังก์ชันที่กำหนดครอบคลุมตัวแปรอินพุตทั้งหมดสามตัว แต่สองตัวในจำนวนนี้มีค่าที่กำหนดไว้ล่วงหน้า ด้วยเหตุนี้ จึงอนุญาตให้เรียกใช้ฟังก์ชันที่มีอาร์เรย์ขององค์ประกอบเชิงโต้แย้งตั้งแต่หนึ่งถึงสามองค์ประกอบได้

 print(arithmetics(1)) # returns 1
print(arithmetics(2, 5)) # returns -3
print(arithmetics(10, 3, 4)) # returns 11

แม้ว่าวิธีการนี้จะนำเสนอช่องทางที่หลากหลายสำหรับการเรียกใช้ฟังก์ชัน แต่ท้ายที่สุดก็พิสูจน์ได้ว่าเป็นวิธีแก้ปัญหาที่ไม่ยั่งยืนเนื่องจากมีข้อจำกัดหลายประการ

อาร์กิวเมนต์ที่ส่งผ่านต้องเป็นประเภทที่เป็นจำนวนเต็มหรือทศนิยม

ดูเหมือนจะไม่มีการเปลี่ยนแปลงที่เห็นได้ชัดในการทำงานของฟังก์ชันเฉพาะนี้ ส่งผลให้ไม่สามารถดำเนินการต่างๆ ได้ เช่น การคำนวณพื้นที่ของรูปทรงที่กำหนด หรือการพิมพ์ข้อความ “Hello World”

วิธีที่ 2: การใช้อาร์กิวเมนต์ของตัวแปร

หากต้องการใช้การโอเวอร์โหลดอาร์กิวเมนต์ของตัวแปรใน Python จำเป็นต้องรวมพารามิเตอร์ “args” ในขณะที่กำหนดฟังก์ชัน คุณลักษณะนี้ช่วยให้สามารถส่งผ่านอาร์กิวเมนต์ตำแหน่งหลายตำแหน่งระหว่างการเรียกใช้ฟังก์ชันได้ สามารถดูตัวอย่างการสาธิตได้ที่ด้านล่างนี้:

 def arithmetics(a, *args):
    """
    Arguments:
    a: The first number.
    *args: A variable number of arguments (optional).
    """
    args_sum = 0

    for num in args:
        args_sum *= num

    return a - args_sum

print(arithmetics(1)) # returns 1
print(arithmetics(2, 5)) # returns 2
print(arithmetics(10, 3, 4, 2, 4, 6)) # returns 10

ฟังก์ชันดังกล่าวต้องใช้พารามิเตอร์สองตัว พารามิเตอร์บังคับหนึ่งตัวที่กำหนดให้เป็น “a” และพารามิเตอร์ทางเลือกที่เรียกว่า “args” อนุญาตให้รวมอาร์กิวเมนต์เพิ่มเติมจำนวนเท่าใดก็ได้ตามต้องการ

แม้ว่าความสามารถในการรับอินพุตจำนวนมาก แต่ฟังก์ชันเฉพาะนี้ยังมีข้อจำกัดในความสามารถในการดำเนินการทางคณิตศาสตร์นอกเหนือจากการคูณแบบธรรมดา เนื่องจากฟังก์ชันนี้ใช้กระบวนการคูณกับตัวแปรที่แสดงโดยคีย์เวิร์ด args เท่านั้น

ในการดำเนินการชุดของการดำเนินการในบริบททางโปรแกรม มักจะจำเป็นต้องรวมคำสั่งแบบมีเงื่อนไขไว้ในโค้ดของตัวเอง อย่างไรก็ตาม เนื่องจากจำนวนเงื่อนไขที่พิจารณาเพิ่มขึ้น ความซับซ้อนของงานการเขียนโปรแกรมก็เช่นกัน

วิธีที่ 3: การใช้เครื่องมือตกแต่งการจัดส่งหลายรายการ

Multiple Dispatch Decorator เป็นไลบรารี Python ที่ช่วยให้สามารถสร้างการใช้งานหรืออินสแตนซ์ต่างๆ ของฟังก์ชันเดี่ยวได้ ขึ้นอยู่กับประเภทของอินพุตที่ได้รับ การทำเช่นนี้อาจสร้างฟังก์ชันที่เหมือนกันกับโครงสร้างข้อมูลที่แตกต่างกันและเปลี่ยนแปลงพฤติกรรมทั้งหมดได้

หากต้องการใช้การตกแต่งการจัดส่งแบบหลายวิธี ให้ปฏิบัติตามระเบียบการเหล่านี้:

⭐ ติดตั้ง multipledispath ในสภาพแวดล้อม Python ของคุณ:

 pip install multipledispatch

⭐ ตกแต่งฟังก์ชั่นของคุณด้วย @dispatch มัณฑนากร @dispatch มัณฑนากรคือมัณฑนากร Python ที่ให้คุณปรับใช้การจัดส่งหลายรายการได้ มันจะส่งฟังก์ชันที่เหมาะสมโดยอัตโนมัติตามอาร์กิวเมนต์ที่คุณส่งไป คุณสามารถใช้เครื่องมือตกแต่ง @dispatch ได้โดยทำตามรูปแบบนี้:

 from multipledispatch import dispatch

@dispatch(data type1, data type2, data typeX)
def your_function(a, b, c, x):
    pass
    # perform your operations here

พิจารณาสถานการณ์ที่เราใช้การใช้ตัวตกแต่งการจัดส่งหลายรายการเพื่ออำนวยความสะดวกในแนวคิดของฟังก์ชันโอเวอร์โหลดภายในภาษาการเขียนโปรแกรม Python:

 from multipledispatch import dispatch

@dispatch(int, int)
def add(a, b):
    """
    Arguments:
    a: Any integer.
    b: Any integer.
    """
    return a \+ b

@dispatch(int, list)
def add(a, b):
    """
    Arguments:
    a: Any integer.
    b: Any Python list.
    """
    b.append(a)
    return b

# returns 3
print(add(1, 2))

# returns [2, 3, 4, 5, 'w', 'done', 1]
print(add(1, [2, 3, 4, 5, 'w', 'done'])) 

ส่วนของโค้ดที่กล่าวมาข้างต้นจะสร้างอินสแตนซ์ของฟังก์ชัน add() สองรายการแยกกัน โดยแต่ละเหตุการณ์ตามลำดับจะยอมรับและประมวลผลพารามิเตอร์ที่แตกต่างกัน โดยเฉพาะอย่างยิ่ง การจุติมาเกิดครั้งนั้นได้รับและคำนวณผลรวมของค่าตัวเลขสองค่าที่แสดงเป็นประเภทข้อมูลจำนวนเต็ม ซึ่งท้ายที่สุดแล้วจะให้ผลลัพธ์รวมในแง่ของผลลัพธ์ของการดำเนินการทางคณิตศาสตร์

ในการสลับรูปแบบ การวนซ้ำครั้งต่อไปของการดำเนินการนี้เกี่ยวข้องกับการยอมรับพารามิเตอร์สองตัว จำนวนเต็มและคอลเลกชันตามลำดับ ต่อจากนั้นพารามิเตอร์ดังกล่าวจะถูกเพิ่มต่อท้ายซีรีส์และส่งคืนเป็นการสะสมที่แก้ไข

/th/images/using-the-dispatch-decorator-for-method-overloading.jpg

วิธีการโอเวอร์โหลดฟังก์ชันใน Python นี้ให้ความยืดหยุ่นอย่างมาก โดยเฉพาะอย่างยิ่ง หากคุณต้องการเปลี่ยนพฤติกรรมของเมธอดของคุณ คุณสามารถเรียนรู้เพิ่มเติมจาก เอกสารการจัดส่งหลายฉบับ

แนวทางที่ดีที่สุดในการโอเวอร์โหลดฟังก์ชันใน Python

การเลือกวิธีการที่เหมาะสมสำหรับการทำงานเกินพิกัดควรสอดคล้องกับวัตถุประสงค์ที่ตั้งใจไว้ ในกรณีที่สามารถบรรลุผลลัพธ์ที่ต้องการได้โดยใช้อาร์กิวเมนต์เริ่มต้นหรือตัวแปร อาจไม่จำเป็นต้องใช้ตัวตกแต่งแบบหลายการจัดส่ง อย่างไรก็ตาม ในกรณีส่วนใหญ่ อย่างหลังนำเสนอตัวเองว่าเป็นโซลูชันที่มีประสิทธิภาพและแม่นยำกว่า เนื่องจากความสามารถในการรองรับอาร์กิวเมนต์ประเภทต่างๆ ในขณะที่ยังคงรักษาประสิทธิภาพสูงสุดไว้

มัณฑนากรที่ให้มานำเสนอวิธีการที่หรูหราและหลากหลายสำหรับการนำฟังก์ชันโอเวอร์โหลดไปใช้ภายในภาษาการเขียนโปรแกรม Python ช่วยให้สามารถสร้างการใช้งานต่างๆ ของฟังก์ชันเดี่ยวได้ ขึ้นอยู่กับลักษณะของพารามิเตอร์

การใช้วิธีนี้ช่วยให้สามารถพัฒนาฟังก์ชันอเนกประสงค์ที่สามารถรองรับประเภทพารามิเตอร์ได้หลากหลาย โดยขจัดข้อกำหนดสำหรับข้อความสั่งแบบมีเงื่อนไขที่ซับซ้อนเพื่อให้บรรลุความสามารถในการปรับตัวดังกล่าว