มีความแตกต่างระหว่าง "Raise except ()" และ "Raise except" โดยไม่มีวงเล็บหรือไม่


100

การกำหนดข้อยกเว้นแบบไม่มีพารามิเตอร์:

class MyException(Exception):
    pass

เมื่อยกขึ้นมีความแตกต่างระหว่าง:

raise MyException

และ

raise MyException()

ฉันไม่พบเลย มันเป็นเพียงไวยากรณ์ที่มากเกินไปหรือไม่?


1
อ่านคำตอบนี้: stackoverflow.com/questions/13052991/…
satoru

1
พูดอย่างเคร่งครัดมันไม่ใช่ไวยากรณ์ Python ไม่สามารถรู้ได้ว่าจะได้รับคลาสหรืออินสแตนซ์จนกระทั่งรันไทม์
asmeurer

คำตอบ:


116

คำตอบสั้น ๆ คือทั้งสองอย่างraise MyExceptionและraise MyException()ทำสิ่งเดียวกัน แบบฟอร์มแรกนี้จะสร้างอินสแตนซ์ข้อยกเว้นของคุณโดยอัตโนมัติ

ส่วนที่เกี่ยวข้องจากเอกสารระบุว่า " Raiseประเมินนิพจน์แรกเป็นอ็อบเจ็กต์ข้อยกเว้นซึ่งต้องเป็นคลาสย่อยหรืออินสแตนซ์ของ BaseException หากเป็นคลาสอินสแตนซ์ข้อยกเว้นจะได้รับเมื่อจำเป็นโดยการสร้างอินสแตนซ์คลาสด้วย ไม่มีข้อโต้แย้ง "

แม้ว่าความหมายจะเหมือนกัน แต่รูปแบบแรกจะเร็วกว่าด้วยกล้องจุลทรรศน์และรูปแบบที่สองมีความยืดหยุ่นมากกว่า (เพราะคุณสามารถส่งผ่านข้อโต้แย้งได้หากจำเป็น)

รูปแบบปกติที่คนส่วนใหญ่ใช้ใน Python (เช่นในไลบรารีมาตรฐานในแอปพลิเคชันยอดนิยมและในหนังสือหลายเล่ม) คือการใช้raise MyExceptionเมื่อไม่มีข้อโต้แย้ง ผู้คนจะสร้างอินสแตนซ์ของข้อยกเว้นโดยตรงเมื่อจำเป็นต้องส่งผ่านข้อโต้แย้งบางประการเท่านั้น ตัวอย่างเช่น: raise KeyError(badkey).


19
ทำไมรูปแบบแรก (ไม่มีวงเล็บ) จึงเร็วกว่าด้วยกล้องจุลทรรศน์?
jamesdlin

16
@jamesdlin เนื่องจากรหัส C ที่ใช้ในการสร้างอินสแตนซ์อัตโนมัติไม่มีค่าใช้จ่ายที่ตีความมากกว่ามาจากการที่คุณโทรออกด้วยตัวเอง
Raymond Hettinger

4

มองไปที่เอกสารสำหรับraiseคำสั่ง มันกำลังสร้างอินสแตนซ์ของMyException.


1
เป็นที่น่าสังเกตว่าไวยากรณ์สำหรับraiseมีการเปลี่ยนแปลงเล็กน้อยใน Python 3 ส่วนที่เกี่ยวข้องกับคำถามนี้จะเหมือนกัน ( raise ExceptionTypeยังคงสร้างอินสแตนซ์ของประเภทโดยเรียกตัวสร้างโดยไม่มีข้อโต้แย้ง)
Blckknght

0

ใช่มีความแตกต่างระหว่างValueErrorและValueError()

ValueErrorเป็นคลาสในขณะที่ValueError()สร้างอินสแตนซ์ของคลาส นี่คือเหตุผลที่type(ValueError) is typeและtype(ValueError()) is ValueError

จุดประสงค์เดียวraiseคือการเพิ่มข้อยกเว้น

เมื่อเราใช้ValueErrorคลาสจะถูกเรียกซึ่งจะเรียกใช้คอนสตรัคเตอร์ ValueError()

เมื่อเราใช้ValueError()วิธีValueError()นี้จะถูกเรียกโดยตรง

บันทึก: raise ValueError # shorthand for 'raise ValueError()'

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