การใช้ฟังก์ชัน super() ในคลาส Python
ประเด็นที่สำคัญ
การใช้ฟังก์ชัน super()
ของ Python ช่วยอำนวยความสะดวกในการเรียกใช้เมธอดภายในคลาสย่อยโดยการเข้าถึงซูเปอร์คลาส ดังนั้นจึงปรับปรุงกระบวนการปรับใช้การสืบทอดและการแทนที่เมธอดในลักษณะที่หรูหรา
ฟังก์ชัน super()
มีความเชื่อมโยงที่สำคัญกับ Method Resolution Order (MRO) ใน Python ซึ่งควบคุมลำดับที่คลาสบรรพบุรุษจะถูกพิจารณาอย่างละเอียดเพื่อหาเมธอดและคุณสมบัติระหว่างการแก้ไขเมธอด
การใช้ super()
ภายใน Constructor ของคลาสเป็นแนวทางทั่วไปสำหรับการสร้างคุณลักษณะที่ใช้ร่วมกันในคลาสพาเรนต์ ในขณะเดียวกันก็กำหนดคุณลักษณะเฉพาะในคลาสรองด้วย ความล้มเหลวในการใช้งาน super()
อาจส่งผลให้เกิดผลลัพธ์ที่ไม่พึงประสงค์ รวมถึงการละเว้นการเริ่มต้นแอตทริบิวต์
ลักษณะพื้นฐานประการหนึ่งของภาษาการเขียนโปรแกรม Python คือกระบวนทัศน์การเขียนโปรแกรมเชิงวัตถุ (OOP) ซึ่งช่วยให้สามารถสร้างแบบจำลองที่แสดงถึงวัตถุในชีวิตจริงและการเชื่อมต่อระหว่างกันในลักษณะที่มีโครงสร้าง
ในบริบทของการเขียนโปรแกรมด้วย Python เป็นเรื่องปกติที่จะใช้การสืบทอดเพื่อแก้ไขหรือแทนที่คุณสมบัติหรือฟังก์ชันของเอนทิตีหลักของคลาส ภาษามีกลไกที่สะดวกสบายที่เรียกว่าฟังก์ชัน"super()“ซึ่งช่วยให้สามารถเรียกเมธอดของคลาสที่เหนือกว่าจากภายในคลาสรองได้
super() คืออะไร และเหตุใดคุณจึงต้องการมัน
การสืบทอดจากคลาสที่มีอยู่ทำให้สามารถสร้างคลาสใหม่ที่มีคุณสมบัติและพฤติกรรมที่คล้ายกันผ่านกระบวนการสืบทอด นอกจากนี้ เราอาจเลือกที่จะแทนที่วิธีการเฉพาะภายในคลาสย่อยเพื่อให้มีการใช้งานเฉพาะของตนเอง แม้ว่าฟังก์ชันการทำงานใหม่นี้อาจเป็นที่ต้องการ แต่ก็มีบางกรณีที่ควรใช้ทั้งฟังก์ชันดั้งเดิมและฟังก์ชันที่นำมาใช้ใหม่พร้อมกันมากกว่า ในกรณีเช่นนี้ การใช้ฟังก์ชัน super()
ช่วยให้สามารถรวมความสามารถทั้งสองชุดเข้ากับคลาสย่อยได้
เพื่อที่จะใช้ประโยชน์จากคุณลักษณะและวิธีการของซูเปอร์คลาสในการเขียนโปรแกรมเชิงวัตถุ เราอาจจะใช้ฟังก์ชัน super()
ฟังก์ชันนี้มีบทบาทสำคัญในเนื่องจากอำนวยความสะดวกในการใช้งานการสืบทอดและการแทนที่เมธอด ซึ่งเป็นแนวคิดพื้นฐานในการเขียนโปรแกรมเชิงวัตถุ
ซุปเปอร์() ทำงานอย่างไร?
ภายใน พฤติกรรมของฟังก์ชัน super()
นั้นเกี่ยวพันกับแนวคิดของ Method Resolution Order (MRO) ซึ่งเป็นกลไกที่กำหนดโดยอัลกอริทึม C3 linearization ใน Python
นี่คือวิธีการทำงานของ super():
เมื่อเรียก super()
ภายในวิธีการของคลาสย่อยใน Python ภาษาจะระบุทั้งคลาสปัจจุบันโดยอัตโนมัติซึ่งมีวิธีการเรียกใช้ เช่นเดียวกับอินสแตนซ์ของคลาสดังกล่าวที่แสดงโดย self
⭐ กำหนดซูเปอร์คลาส: super() รับสองอาร์กิวเมนต์€”คลาสปัจจุบันและอินสแตนซ์€”ซึ่งคุณไม่ต้องการ ให้ผ่านไปได้อย่างชัดเจน ใช้ข้อมูลนี้เพื่อกำหนดซูเปอร์คลาสเพื่อมอบหมายการเรียกเมธอด ซึ่งทำได้โดยการตรวจสอบลำดับชั้นของชั้นเรียนและ MRO
เมื่อซุปเปอร์คลาสถูกระบุแล้ว ฟังก์ชัน super()
จะอนุญาตให้เรียกใช้เมธอดของมันราวกับว่ามันถูกเรียกโดยตรงจากคลาสย่อย ความสามารถนี้อำนวยความสะดวกทั้งการขยายและการแทนที่วิธีการของซูเปอร์คลาส ขณะเดียวกันก็ใช้ประโยชน์จากการใช้งานดั้งเดิมที่จัดทำโดยซูเปอร์คลาส
การใช้ super() ในตัวสร้างคลาส
การผสมผสานการใช้เมธอด super() ภายในตัวสร้างของคลาสเป็นวิธีการที่แพร่หลาย เนื่องจากช่วยให้สามารถเริ่มต้นคุณสมบัติที่ใช้ร่วมกันระหว่างคลาสพี่น้อง ในขณะเดียวกันก็อนุญาตให้มีคุณลักษณะเฉพาะในลูกหลานแต่ละคน
เพื่อแสดงให้เห็นแนวคิดของการสืบทอดในการเขียนโปรแกรมเชิงวัตถุโดยใช้ Python เราสามารถสร้างคลาส “Father” ที่ทำหน้าที่เป็นคลาสพื้นฐานสำหรับคลาสอื่นที่เรียกว่า “Son” คลาส “Son” จะสืบทอดคุณสมบัติและวิธีการจากคลาสแม่ ซึ่งก็คือ “Father” ซึ่งแสดงให้เห็นว่าการสืบทอดช่วยให้สามารถนำโค้ดกลับมาใช้ใหม่และความเป็นโมดูลได้อย่างไร
class Father:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
class Son(Father):
def __init__(self, first_name, last_name, age, hobby):
# Call the parent class constructor (Father)
super().__init__(first_name, last_name)
self.age = age
self.hobby = hobby
def get_info(self):
return f"Son's Name: {self.first_name} {self.last_name}, \
Son's Age: {self.age}, Son's Hobby: {self.hobby}"
# Create an instance of the Son class
son = Son("Pius", "Effiong", 25, "Playing Guitar")
# Access attributes
print(son.get_info())
ภายในขอบเขตของคอนสตรัคเตอร์ของคลาส Son
ความจำเป็นในการเรียกการอุปถัมภ์ของคลาสแม่นั้นจะดำเนินการผ่านการกระทำอันมหัศจรรย์ของการเรียกฟังก์ชัน super()
การดำเนินการที่สำคัญนี้กระตุ้นให้เกิดการเริ่มต้นของตัวสร้างคลาส พ่อ
ที่เป็นบิดา โดยเสนอตัวระบุที่สำคัญยิ่งที่นับถือสองตัวในรูปแบบของตัวแปร first\_name
และ Last\_name
ในลักษณะนี้ ชนชั้น"พ่อ"ยังคงรักษาความสามารถในการบรรลุและกำหนดการกำหนดชื่อเหล่านี้ได้อย่างถูกต้อง แม้ว่าจะมีลักษณะเป็น"บุตร"ก็ตาม
ในกรณีที่ไม่ได้เรียกใช้เมธอด super()
ภายในโครงสร้าง
...
class Son(Father):
def __init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...
ในกรณีที่คุณพยายามเรียกใช้เมธอด get\_info
ในช่วงหัวเลี้ยวหัวต่อนี้ จะส่งผลให้เกิดการสร้าง AttributeError
เนื่องจากยังไม่ได้เตรียมใช้งานแอตทริบิวต์ self.first\_name
และ self.last\_name
การใช้ super() ใน Class Method
เราสามารถใช้ฟังก์ชัน super() ไม่เพียงแต่ภายในขอบเขตของขั้นตอนการสร้างเท่านั้น แต่ยังรวมถึงวิธีการที่หลากหลายเพื่อเพิ่มหรือแทนที่ฟังก์ชันการทำงานของแนวทางระเบียบวิธีของคลาสผู้ปกครองด้วย
class Father:
def speak(self):
return "Hello from Father"
class Son(Father):
def speak(self):
# Call the parent class's speak method using super()
parent_greeting = super().speak()
return f"Hello from Son\n{parent_greeting}"
# Create an instance of the Son class
son = Son()
# Call the speak method of the Son class
son_greeting = son.speak()
print(son_greeting)
คลาส Son
ใน Python ได้รับการออกแบบมาเพื่อสืบทอดคุณสมบัติและวิธีการจากคลาสพาเรนต์หรือคลาส Father
รวมถึงเมธอด speak()
ด้วยการใช้ฟังก์ชัน super().speak()
ภายในเมธอด พูด()
ของคลาส Son
จะทำให้สามารถเรียกใช้เมธอด พูด ()
ดั้งเดิมของคลาส Father
ได้อย่างมีประสิทธิภาพ ข้อมูลเพิ่มเติมหรือข้อความเฉพาะของคลาส Son
ในกรณีที่เมธอดแทนที่เมธอดอื่นโดยไม่ใช้ฟังก์ชัน super()
ที่ให้มา ฟังก์ชันที่ต้องการจากคลาสพาเรนต์จะไม่ถูกดำเนินการ ด้วยเหตุนี้ จึงอาจส่งผลให้เกิดพฤติกรรมที่ไม่ได้ตั้งใจอันเนื่องมาจากวิธีการใหม่และแตกต่างโดยสิ้นเชิงที่มาแทนที่ฟังก์ชันการทำงานแบบเดิม
ทำความเข้าใจลำดับการแก้ปัญหาวิธีการ
Method Resolution Order (MRO) หมายถึงลำดับชั้นของลำดับความสำคัญที่กำหนดลำดับที่ Python จะค้นหาวิธีการและคุณลักษณะเมื่อต้องจัดการกับโครงสร้างคลาสที่ซับซ้อนที่เกี่ยวข้องกับการสืบทอดหลายรายการ กลไกนี้ช่วยให้แน่ใจว่ามีการเรียกวิธีการที่เหมาะสมตามตัวเลือกที่มีอยู่ภายในคลาสพาเรนต์ที่เกี่ยวข้อง ดังนั้นจึงแก้ไขความคลุมเครือที่อาจเกิดขึ้นจากคำจำกัดความที่ทับซ้อนกัน
class Nigeria():
def culture(self):
print("Nigeria's culture")
class Africa():
def culture(self):
print("Africa's culture")
เมื่อสร้างตัวอย่างคลาสลากอสและเรียกใช้วิธีการเพาะเลี้ยง เหตุการณ์จำนวนหนึ่งเกิดขึ้นซึ่งมีส่วนช่วยในการทำงานโดยรวมของวัตถุ การเรียกใช้โค้ดดำเนินการผ่านหลายขั้นตอนที่เกี่ยวข้องกับการจัดการข้อมูล การดึงข้อมูลจากแหล่งภายนอก และการประยุกต์ใช้อัลกอริธึมต่างๆ เพื่อวิเคราะห์แง่มุมทางวัฒนธรรมตามพารามิเตอร์อินพุตที่ผู้ใช้ให้มาหรือค่าเริ่มต้นที่ตั้งไว้ใน Constructor ผลลัพธ์ที่ได้คือการประเมินคุณลักษณะทางวัฒนธรรมของเมืองที่ระบุอย่างครอบคลุมตามประเภทลากอส
Python จะค้นหาเมธอด culture
ภายในคลาส Lagos
ก่อน ในกรณีที่ค้นพบวิธีการนี้และพร้อมใช้งาน อัลกอริธึมจะดำเนินการเรียกใช้ต่อไป อย่างไรก็ตาม หากไม่มีวิธีการดังกล่าวหรือไม่สามารถเข้าถึงได้ กระบวนการก็จะเข้าสู่ขั้นตอนต่อไป
ถ้าคลาส Lagos
ไม่มีเมธอด culture()
Python จะค้นหาเมธอดในคลาสพื้นฐานของลำดับชั้นของคลาส โดยเริ่มจากคลาสที่อยู่ในรายการหลังเครื่องหมายทวิภาค ( :
) ซึ่งสืบทอดมาจาก คลาส"ลากอส"ในตัวอย่างนี้ คลาส Lagos
ได้รับการกำหนดให้รับช่วงแรกจากคลาส’Africa และลำดับที่สองจากคลาส'Nigeria
ดังนั้น หากคลาส Lagos
ไม่มีการนำเมธอด culture()
มาใช้ Python จะพยายามค้นหาวิธีการภายในคลาส Africa
ก่อนที่จะค้นหาคลาส Nigeria
การค้นหาวิธีการเฉพาะทางวัฒนธรรมภายในลำดับชั้นที่กำหนดจะดำเนินการผ่านชุดของชั้นเรียนที่ซ้อนกัน โดยแต่ละชั้นเรียนที่ตามมาจะถูกตรวจสอบในกรณีที่พบวิธีการที่ต้องการในนั้น ในกรณีที่ไม่พบวิธีการในระดับเริ่มต้นของการสอบถาม เช่น คลาสแอฟริกัน Python จะเปลี่ยนโฟกัสไปที่คลาสสูงสุดถัดไปในโครงสร้างลำดับชั้น ซึ่งในกรณีนี้จะสอดคล้องกับคลาสไนจีเรีย กระบวนการนี้จะเกิดขึ้นซ้ำอีกครั้งเมื่อลงจากแผนผังคลาส โดยขยายจากทั่วไปที่สุดไปสู่เฉพาะเจาะจงน้อยที่สุด จนกระทั่งถึงเวลาที่เมธอดที่ต้องการไม่สามารถอยู่ในซูเปอร์คลาสใด ๆ ที่พบได้ ในช่วงหัวเลี้ยวหัวต่อนั้น มีการยกข้อยกเว้นขึ้นเพื่อระบุผลลัพธ์การค้นหาที่ไม่ประสบผลสำเร็จ
ลำดับการแก้ปัญหาวิธีการ (MRO) สำหรับลากอสจะแสดงเป็นเส้นตรง โดยเริ่มจากด้านซ้ายและเลื่อนไปทางขวา
ข้อผิดพลาดทั่วไปและแนวทางปฏิบัติที่ดีที่สุด
เมื่อใช้ฟังก์ชัน super()
สิ่งสำคัญคือต้องระวังข้อผิดพลาดที่อาจเกิดขึ้นเพื่อให้แน่ใจว่าจะได้รับประสบการณ์ที่ราบรื่นและมีประสิทธิภาพ
⭐ โปรดคำนึงถึงลำดับการแก้ไขวิธีการ โดยเฉพาะอย่างยิ่งในสถานการณ์การสืบทอดหลายรายการ หากคุณต้องการใช้การสืบทอดหลายรายการที่ซับซ้อน คุณควรคุ้นเคยกับ อัลกอริธึม C3 Linearization ที่ Python ใช้ในการกำหนด MRO
ควรหลีกเลี่ยงการพึ่งพาแบบวงกลมภายในลำดับชั้นของคลาส เนื่องจากอาจส่งผลให้เกิดพฤติกรรมที่ไม่แน่นอนและคาดเดาได้ยาก
เมื่อทำงานกับลำดับชั้นของคลาสที่ซับซ้อนซึ่งเกี่ยวข้องกับการใช้ฟังก์ชัน super()
สิ่งสำคัญคือต้องรักษา codebase ที่ชัดเจนและมีการบันทึกไว้อย่างดี สิ่งนี้ไม่เพียงแต่รับประกันการทำงานที่เหมาะสม แต่ยังส่งเสริมความเข้าใจในหมู่นักพัฒนาคนอื่นๆ ที่อาจจำเป็นต้องดำเนินการหรือแก้ไขโค้ดในอนาคต ด้วยการแสดงความคิดเห็นที่กระชับแต่ให้ข้อมูล คุณสามารถเพิ่มความสามารถในการอ่านและการบำรุงรักษาโครงการของคุณ อำนวยความสะดวกในการทำงานร่วมกัน และลดข้อผิดพลาดหรือความสับสนที่อาจเกิดขึ้น
ใช้ super() อย่างถูกวิธี
การใช้ฟังก์ชัน super()
ของ Python แสดงถึงแง่มุมที่ขาดไม่ได้ของกระบวนทัศน์การเขียนโปรแกรมเชิงวัตถุ โดยเฉพาะอย่างยิ่งในส่วนที่เกี่ยวข้องกับการอำนวยความสะดวกในการสืบทอดและการแทนที่เมธอด การเข้าใจความซับซ้อนที่เกี่ยวข้องกับเอนทิตีการทำงานนี้และการปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดที่กำหนดไว้ช่วยให้สามารถพัฒนาแอปพลิเคชันซอฟต์แวร์ที่ยั่งยืนและมีทรัพยากรมากขึ้นภายในระบบนิเวศของ Python