ทำไมส่งคืน NotImplemented แทนการเพิ่ม NotImplementedError


282

NotImplementedงูหลามมีเดี่ยวที่เรียกว่า

ทำไมบางคนต้องการกลับมาNotImplementedแทนที่จะยกNotImplementedErrorข้อยกเว้น? มันจะไม่ทำให้การค้นหาข้อบกพร่องยากขึ้นเช่นรหัสที่ใช้วิธีการที่ไม่ถูกต้องหรือไม่

คำตอบ:


280

เป็นเพราะ__lt__()และวิธีการเปรียบเทียบที่เกี่ยวข้องมักใช้โดยอ้อมในประเภทรายการและเช่น บางครั้งอัลกอริทึมจะเลือกลองอีกวิธีหนึ่งหรือเลือกผู้ชนะเริ่มต้น การยกข้อยกเว้นจะแยกออกจากการเรียงลำดับเว้นแต่จะถูกจับในขณะที่NotImplementedไม่ได้รับการยกและสามารถใช้ในการทดสอบเพิ่มเติม

http://jcalderone.livejournal.com/32837.html

ในการสรุปลิงก์นั้น:

" NotImplementedส่งสัญญาณไปยังรันไทม์ที่ควรให้คนอื่นพึงพอใจกับการดำเนินการในนิพจน์a == bหากa.__eq__(b)ส่งคืนNotImplementedPython จะพยายามb.__eq__(a)หากbรู้ว่าจะส่งคืนได้เพียงพอTrueหรือหากเป็นFalseเช่นนั้นนิพจน์จะประสบความสำเร็จหากไม่เป็นเช่นนั้น ถอยกลับไปใช้พฤติกรรมในตัว (ซึ่งขึ้นอยู่กับตัวตนของ==และ!=) "


5
ฉันจะใช้มันอย่างระมัดระวังเนื่องจากลิงค์นี้ชี้ให้เห็นใกล้ถึงจุดสิ้นสุดของเอกสาร
เจสันคูน

16
เมื่อ Python interpreter ตรวจสอบว่ามีการa.__eq__(b)ส่งคืน NotImplemented ไม่สามารถจับ NotImplementedError แทนได้อย่างง่ายดายb.__eq__(a)หรือไม่(และโทรหรืออะไรก็ตาม)
Veky

24
@Veky การเพิ่มข้อยกเว้นอาจมีค่าใช้จ่ายสูงกว่า ค่าใช้จ่ายใด ๆ ในการดำเนินการเรียงลำดับจะได้รับการขยายตามขนาดของรายการดังนั้นแม้ว่าความแตกต่างนั้นมีขนาดเล็กมาก นอกจากนี้คุณยังไม่ต้องการแยกออกจากลูปของคุณและป้อนเข้าไปใหม่ซึ่งต้องมีการใช้งานแบบลอง / จับได้
SpliFF

3
สำหรับประเด็นแรกการแก้ปัญหาที่รวดเร็วยิ่งขึ้นก็คือการสังเคราะห์ lt โดยอัตโนมัติในฐานะตรงกันข้ามกับ gt แทนที่จะเรียกสิ่งที่จะคืนค่า NotImplemented - เสมอและ Python ไม่ทำเช่นนั้น ฉันไม่คิดว่าความเร็วเป็นเหตุผลที่นี่ และอย่างที่สองฉันไม่เข้าใจสิ่งที่คุณกำลังพูด: การกลับมาจะต้องแยกออกจากลูปมากพอ ๆ กับการเลี้ยงดู ในความเป็นจริงคุณสามารถจินตนาการถึงการส่งคืนเป็นการเพิ่มข้อยกเว้นการส่งคืนพิเศษซึ่งมักจะติดอยู่ในขอบเขตการโทร
Veky

2
>> "ขยายตามขนาดของรายการ" อย่างน้อยถ้าคุณไม่มี O (n) เรียงลำดับโลกที่ควรรู้
Jonathan Hartley

107

เพราะพวกเขามีกรณีการใช้ที่แตกต่างกัน

การอ้างอิงเอกสาร (Python 3.6):

ไม่ได้ดำเนินการ

ควรจะกลับโดยวิธีพิเศษไบนารี (เช่น__eq__(), __lt__(), __add__(), __rsub__()ฯลฯ ) เพื่อแสดงให้เห็นว่าการดำเนินการไม่ได้ดำเนินการที่เกี่ยวกับประเภทอื่น ๆ

ข้อยกเว้น NotImplementedError

[... ] ในคลาสพื้นฐานที่ผู้ใช้กำหนดวิธีนามธรรมควรเพิ่มข้อยกเว้นนี้เมื่อพวกเขาต้องการคลาสที่ได้รับเพื่อแทนที่เมธอดหรือขณะที่คลาสกำลังพัฒนาเพื่อระบุว่าการใช้งานจริงยังคงต้องเพิ่ม

ดูลิงค์สำหรับรายละเอียด


นี่ควรเป็นคำตอบที่ยอมรับได้ มันยิ่งแข็งแกร่งกว่ากรณีใช้งานมันเป็นการบ่งชี้ถึงเจตนา - อันที่มีข้อผิดพลาดที่ส่วนท้ายของสัญญาณชื่อที่เกิดข้อผิดพลาด (เพราะบางสิ่งไม่ได้ถูกนำไปใช้) ส่วนอีกอันหนึ่งไม่ใช่ข้อผิดพลาด แต่ "เหมาะสม" พฤติกรรม. ฉันจะเอาไปเปรียบกับความแตกต่างระหว่างการคืน NaN หรือการเพิ่ม ValueError
Korone

13

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.