简体   繁体   中英

Python: why except is called even after exit

Please check the below code,

import sys
try:
    seq=eval(raw_input("Enter seq number: "))
    if seq <= 0 or seq >= 9999:
       print "Sequence number not in range [0001-9999]"
       sys.exit(1)
except:
      print "!!! Sequence number not in range [0001-9999]"
      sys.exit(1)

I gave a string to eval raw_input function.

$> python test.py
Enter seq number: "12"


Sequence number not in range [0001-9999]
!!! Sequence number not in range [0001-9999]

Why is it not exiting even after receiving exit call?

sys.exit just raises an exception ( SystemExit ), which is then caught. As a demonstration:

import sys
import traceback

try:
    sys.exit(1)
except:
    print "This threw the following exception:"
    traceback.print_exc()
# This threw the following exception:
# Traceback (most recent call last):
#   File "test.py", line 5, in <module>
#     sys.exit(1)
# SystemExit: 1

sys.exit raises the SystemExit exception which is caught by your unnamed exception handler

Note, it is usually not a good idea to have a generic exception handler as its evident here.

So as to avoid catching the SystemExit with your generic exception handler, add another exception handler to handler your SystemExit

>>> try:
    seq=eval(raw_input("Enter seq number: "))
    if seq <= 0 or seq >= 9999:
       print "Sequence number not in range [0001-9999]"
       sys.exit(1)
except SystemExit:
    pass
except Exception:
      print "!!! Sequence number not in range [0001-9999]"
      sys.exit(1)

This is an excellent case why you should never use a bare except. Invalid numbers are ValueErrors, so:

import sys
try:
    seq = int(raw_input("Enter seq number: "))
    if seq <= 0 or seq >= 9999:
       raise ValueError('sequence number not in range [0001-9999]')
except ValueError as e:
    print e
    sys.exit(1)

Output:

C:\>test
Enter seq number: 10000
sequence number not in range [0001-9999]

C:\>test
Enter seq number: abc
invalid literal for int() with base 10: 'abc'

C:\>test
Enter seq number: 5

Note eval is also frowned upon, because it will execute whatever the user types, such as import shutil; shutil.rmtree('/') import shutil; shutil.rmtree('/') .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM